<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.adatis.co.uk/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Adatis BI Blogs</title><link>http://blogs.adatis.co.uk/blogs/</link><description /><dc:language>en-US</dc:language><generator>CommunityServer 2007 SP2 (Build: 20611.960)</generator><item><title>Data Quality Services (RC0) - Cleanse and Train the KB</title><link>http://blogs.adatis.co.uk/blogs/victormendes/archive/2012/01/09/data-quality-services-rc0-cleanse-and-train-the-kb.aspx</link><pubDate>Mon, 09 Jan 2012 16:10:00 GMT</pubDate><guid isPermaLink="false">8d7d37f8-4a66-4c95-9fba-293fa87607dc:10133</guid><dc:creator>Victor Mendes</dc:creator><slash:comments>0</slash:comments><description>This post will show a new KB (Knowledge Base) being trained using the &lt;a title="DQS - RC0 New Features" href="http://blogs.msdn.com/b/dqs/archive/2011/11/29/sql-server-2012-rc0-what-s-new-in-dqs.aspx" target="_blank"&gt;new feature&lt;/a&gt; via domain management which allows the KB to import the knowledge gained from a cleansing project. In the previous release, CTP3, the KB was trained using Knowledge Discovery from either a table or excel file. This could also have been done interactively via domain management, but not directly from a cleansed project.   &lt;p&gt;In this example we will retrain the new KB by importing knowledge learnt from two cleansed samples of data. The outputs of the cleansed projects will be imported into the KB. Before retraining our KB we will need to tweak one of the cleansing configuration settings. This will retrain our new KB faster.&lt;/p&gt;  &lt;h3&gt;New Knowledge Base&lt;/h3&gt;  &lt;p&gt;&lt;font color="#ff0000"&gt;&lt;/font&gt;&lt;/p&gt; If you have not created a KB before a step by step guide can be found &lt;a title="SQL Server Data Quality Services – Creating a Knowledge Base" href="http://www.bimonkey.com/2011/08/sql-server-data-quality-services-creating-a-knowledge-base/" target="_blank"&gt;here&lt;/a&gt;.   &lt;p&gt;The new KB was called UK Counties. A single domain value was used and it was called UK County (Full Name). &lt;/p&gt;  &lt;p&gt;Using the Knowledge Discovery feature we first trained our empty KB with a unique list of UK Counties. The Domain Management feature could also have been used by entering domain values or importing them from an excel file. &lt;/p&gt;  &lt;p&gt;Training the KB doesn&amp;#39;t stop there, further training is required to expand the KB knowledge. Interactively we could add new domain values or synonyms to the already existing values such as Bucks for Buckinghamshire if we knew this was a potential synonym. For this example we will be using the knowledge gained from our cleansing project to retrain our KB.&lt;/p&gt;  &lt;p&gt;Below is a screen shot of some of the domain values prior to retraining and being published to the DQS server.&lt;/p&gt; &lt;a title="graphic2F" name="graphic2F"&gt;&lt;/a&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/victormendes/A90_NewKB_0645277C.png"&gt;&lt;img style="border-width:0px;padding-top:0px;padding-right:0px;padding-left:0px;display:inline;background-image:none;" title="A90_NewKB" border="0" alt="A90_NewKB" src="http://blogs.adatis.co.uk/blogs/victormendes/A90_NewKB_thumb_625C5021.png" width="501" height="354" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h3&gt;Configuring Cleansing Projects&lt;/h3&gt;  &lt;p&gt;During cleansing a computer-assisted process will analyse how the source data conforms to the knowledge in the KB and a confidence level is determined. There are two confidence level thresholds: suggestions and auto corrections. Suggestions can be approved or rejected. Auto corrections are already approved, but it is possible to reject them as well.&lt;/p&gt;  &lt;p&gt;These thresholds can be set in the general settings for a cleansing project from the DQS configuration area. &lt;/p&gt;  &lt;p&gt;By default 0.6 (60%) and 0.8 (80%) are set respectively for suggestions and auto corrections. &lt;/p&gt;  &lt;p&gt;As the KB is still young we need to retrain it with some samples of our real data and therefore make more suggestions. Hence we will reduce the confidence level percentage for suggestions down to 0.4 (40%). &lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/victormendes/B02_Config_6BF9A1FC.png"&gt;&lt;img style="border-width:0px;padding-top:0px;padding-right:0px;padding-left:0px;display:inline;background-image:none;" title="B02_Config" border="0" alt="B02_Config" src="http://blogs.adatis.co.uk/blogs/victormendes/B02_Config_thumb_1F556559.png" width="292" height="140" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;N.B. This can go the other way where too many suggestions are given or a source value could be mapped to a completely incorrect domain value. As the knowledge of KB increases the confidence level for suggestions should also be increased to isolate new values and minimise interactive cleaning.&lt;/em&gt;&lt;/p&gt;  &lt;h3&gt;Training the KB&lt;/h3&gt;  &lt;p&gt;There are a number of ways to train the KB&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Knowledge Discovery,&amp;nbsp; or &lt;/li&gt;    &lt;li&gt;Domain Management by either      &lt;ol&gt;       &lt;li&gt;Interactively entering or editing domain values, &lt;/li&gt;        &lt;li&gt;Importing domain values from an excel file, or &lt;/li&gt;        &lt;li&gt;Using the completed output of a cleansing project. &lt;/li&gt;     &lt;/ol&gt;   &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;The final option is the new feature added to RC0 which makes managing knowledge within the KB simpler.&lt;/p&gt;  &lt;p&gt;Let’s look at our first sample of data.&lt;/p&gt;  &lt;p&gt;&lt;a title="graphic32" name="graphic32"&gt;&lt;/a&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/victormendes/B03_Config_64F9EF77.png"&gt;&lt;img style="border-width:0px;padding-top:0px;padding-right:0px;padding-left:0px;display:inline;background-image:none;" title="B03_Config" border="0" alt="B03_Config" src="http://blogs.adatis.co.uk/blogs/victormendes/B03_Config_thumb_7D1D59D2.png" width="156" height="218" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;You will notice a number of data quality issues such as postcode and county, town and county or a short county name. Our objective is to clean this data to the County Full Name domain value in the KB.&lt;/p&gt;  &lt;p&gt;If you have not created a data quality project before a step by step guide can be found &lt;a title="Create a Data Quality Project" href="http://technet.microsoft.com/en-us/library/hh510393(SQL.110).aspx" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;We will skip to the end of our cleansing project and analyse the results. &lt;/p&gt;  &lt;p&gt;On successful completion we can see from the results that 0 records were corrected and 7 records have suggested domain values. We can now perform an interactive cleanse by which we approve or reject the suggestions made. Where the data confidence level has not been met for suggestions of 40% or auto corrections of 80% it will be considered as a new value. For this particular example we should not be expecting new values as we have a definitive list of counties and therefore we will need to add corrected values manually. &lt;/p&gt;  &lt;p&gt;Let’s start with the suggested values. All are correct and therefore only need to be approved. We approve all values by clicking the check box under the Approve column or we can click the Approve All icon &lt;a title="graphic39" name="graphic39"&gt;&lt;/a&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/victormendes/C08_DQP_63FE2B93.png"&gt;&lt;img style="border-width:0px;padding-top:0px;padding-right:0px;padding-left:0px;display:inline;background-image:none;" title="C08_DQP" border="0" alt="C08_DQP" src="http://blogs.adatis.co.uk/blogs/victormendes/C08_DQP_thumb_23C81219.png" width="32" height="37" /&gt;&lt;/a&gt;. All suggested values will move into the Corrected tab area.&lt;/p&gt;  &lt;p&gt;&lt;a title="graphic37" name="graphic37"&gt;&lt;/a&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/victormendes/C05_DQP_3402CA74.png"&gt;&lt;img style="border-width:0px;padding-top:0px;padding-right:0px;padding-left:0px;display:inline;background-image:none;" title="C05_DQP" border="0" alt="C05_DQP" src="http://blogs.adatis.co.uk/blogs/victormendes/C05_DQP_thumb_05A944C7.png" width="704" height="219" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Now let’s review the new tab below. Three new values in the source data have been found, the analysis could not confidently associate any of the three values with a confidence level greater than or equal to 40% and therefore has presented them as new values. &lt;/p&gt;  &lt;p&gt;&lt;a title="graphic38" name="graphic38"&gt;&lt;/a&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/victormendes/C06_DQP_53457147.png"&gt;&lt;img style="border-width:0px;padding-top:0px;padding-right:0px;padding-left:0px;display:inline;background-image:none;" title="C06_DQP" border="0" alt="C06_DQP" src="http://blogs.adatis.co.uk/blogs/victormendes/C06_DQP_thumb_20E19DC8.png" width="704" height="135" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Looking at the values we know the county is Middlesex as is in the KB, hence we manually enter this value into the Correct to column. Now we can approve each value or we can click the Approve All icon.&lt;/p&gt;  &lt;p&gt;&lt;a title="graphic3A" name="graphic3A"&gt;&lt;/a&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/victormendes/C07_DQP_5A9552F2.png"&gt;&lt;img style="border-width:0px;padding-top:0px;padding-right:0px;padding-left:0px;display:inline;background-image:none;" title="C07_DQP" border="0" alt="C07_DQP" src="http://blogs.adatis.co.uk/blogs/victormendes/C07_DQP_thumb_6723000E.png" width="704" height="141" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;All values have now moved to the corrected tab.&lt;/p&gt; &lt;a title="graphic3B" name="graphic3B"&gt;&lt;/a&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/victormendes/C09_DQP_3452F99A.png"&gt;&lt;img style="border-width:0px;padding-top:0px;padding-right:0px;padding-left:0px;display:inline;background-image:none;" title="C09_DQP" border="0" alt="C09_DQP" src="http://blogs.adatis.co.uk/blogs/victormendes/C09_DQP_thumb_330E60BB.png" width="704" height="217" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Our data cleanse results are now ready for final review before finishing the project. Finishing a project no longer allows the project to be re-run for cleansing purposes as the knowledge gained would be lost, however you will be able to interactively clean to alter the final results. It’s these results and knowledge that is imported back into the KB, but the project must be marked as finished.&lt;/p&gt;  &lt;p&gt;It is the CountyName_Source that we want to feed back to the KB as synonyms for the domain values found or modified in the CountyName_Output. &lt;/p&gt; &lt;a title="graphic3C" name="graphic3C"&gt;&lt;/a&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/victormendes/C10_DQP_12A324D8.png"&gt;&lt;img style="border-width:0px;padding-top:0px;padding-right:0px;padding-left:0px;display:inline;background-image:none;" title="C10_DQP" border="0" alt="C10_DQP" src="http://blogs.adatis.co.uk/blogs/victormendes/C10_DQP_thumb_721BE525.png" width="515" height="319" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;To feed this new acquired knowledge we open our KB via Domain Management and can now use the new feature Import project values.&lt;/p&gt;  &lt;p&gt;&lt;a title="graphic3D" name="graphic3D"&gt;&lt;/a&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/victormendes/D01_KBDM_23A752BB.png"&gt;&lt;img style="border-width:0px;padding-top:0px;padding-right:0px;padding-left:0px;display:inline;background-image:none;" title="D01_KBDM" border="0" alt="D01_KBDM" src="http://blogs.adatis.co.uk/blogs/victormendes/D01_KBDM_thumb_3F4BDEB1.png" width="300" height="174" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;We select the finished cleansing project and uncheck Add values from New Tab.&lt;/p&gt; &lt;a title="graphic3E" name="graphic3E"&gt;&lt;/a&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/victormendes/D02_KBDM_03201309.png"&gt;&lt;img style="border-width:0px;padding-top:0px;padding-right:0px;padding-left:0px;display:inline;background-image:none;" title="D02_KBDM" border="0" alt="D02_KBDM" src="http://blogs.adatis.co.uk/blogs/victormendes/D02_KBDM_thumb_69B80FCE.png" width="473" height="248" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Only the new knowledge from the project has been added to the KB. The Show Only New check box is checked automatically.&lt;/p&gt; &lt;a title="graphic3F" name="graphic3F"&gt;&lt;/a&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/victormendes/D03_KBDM_2262B9DC.png"&gt;&lt;img style="border-width:0px;padding-top:0px;padding-right:0px;padding-left:0px;display:inline;background-image:none;" title="D03_KBDM" border="0" alt="D03_KBDM" src="http://blogs.adatis.co.uk/blogs/victormendes/D03_KBDM_thumb_1DEC3915.png" width="556" height="374" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;If we uncheck the Show Only New check box and scroll down to London and Middlesex you will see the synonyms for these counties have been added to the KB. &lt;/p&gt; &lt;a title="graphic40" name="graphic40"&gt;&lt;/a&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/victormendes/D04_KBDM_41A560AF.png"&gt;&lt;img style="border-width:0px;padding-top:0px;padding-right:0px;padding-left:0px;display:inline;background-image:none;" title="D04_KBDM" border="0" alt="D04_KBDM" src="http://blogs.adatis.co.uk/blogs/victormendes/D04_KBDM_thumb_48586A32.png" width="360" height="255" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;We now publish the KB to the DQS server and are ready to analyse another data sample.&lt;/p&gt; &lt;a title="graphic41" name="graphic41"&gt;&lt;/a&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/victormendes/E01_DQP_59F8AE96.png"&gt;&lt;img style="border-width:0px;padding-top:0px;padding-right:0px;padding-left:0px;display:inline;background-image:none;" title="E01_DQP" border="0" alt="E01_DQP" src="http://blogs.adatis.co.uk/blogs/victormendes/E01_DQP_thumb_20096BAA.png" width="161" height="215" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;As above we create a new cleansing project and analyse the data. The newly found knowledge from the previous cleansing project has corrected five values with 4 values suggested, leaving one value as new.&lt;/p&gt;  &lt;p&gt;If we view the reason column for the corrected tab, four of the values were associated with the synonyms of domain values within the KB from the knowledge learned. &amp;#39;London.&amp;#39; was cleansed and had a confidence greater than or equal to 80% and therefore auto corrected. &lt;/p&gt;  &lt;p&gt;&lt;a title="graphic43" name="graphic43"&gt;&lt;/a&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/victormendes/E03_DQP_680743FA.png"&gt;&lt;img style="border-width:0px;padding-top:0px;padding-right:0px;padding-left:0px;display:inline;background-image:none;" title="E03_DQP" border="0" alt="E03_DQP" src="http://blogs.adatis.co.uk/blogs/victormendes/E03_DQP_thumb_4E9F40C0.png" width="746" height="177" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;In the suggested tab the correct to values are all correct and only need approving.&lt;/p&gt; &lt;a title="graphic44" name="graphic44"&gt;&lt;/a&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/victormendes/E04_DQP_4B9B0011.png"&gt;&lt;img style="border-width:0px;padding-top:0px;padding-right:0px;padding-left:0px;display:inline;background-image:none;" title="E04_DQP" border="0" alt="E04_DQP" src="http://blogs.adatis.co.uk/blogs/victormendes/E04_DQP_thumb_1D417A64.png" width="745" height="147" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The new value failed the confidence level of 40%, however it could have been found and a suggestion made if the threshold was reduced further. This is not a problem as the correct value was entered and approved.&lt;/p&gt;  &lt;p&gt;&lt;a title="graphic45" name="graphic45"&gt;&lt;/a&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/victormendes/E06_DQP_1C3B6D41.png"&gt;&lt;img style="border-width:0px;padding-top:0px;padding-right:0px;padding-left:0px;display:inline;background-image:none;" title="E06_DQP" border="0" alt="E06_DQP" src="http://blogs.adatis.co.uk/blogs/victormendes/E06_DQP_thumb_3BEA4709.png" width="748" height="116" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Finally we review our results and finish the project.&lt;/p&gt; &lt;a title="graphic46" name="graphic46"&gt;&lt;/a&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/victormendes/E07_DQP_46A79E5E.png"&gt;&lt;img style="border-width:0px;padding-top:0px;padding-right:0px;padding-left:0px;display:inline;background-image:none;" title="E07_DQP" border="0" alt="E07_DQP" src="http://blogs.adatis.co.uk/blogs/victormendes/E07_DQP_thumb_1443CADF.png" width="500" height="238" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;We now feed this new knowledge back into the KB via Domain Management.&lt;/p&gt;  &lt;p&gt;&lt;a title="graphic47" name="graphic47"&gt;&lt;/a&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/victormendes/E08_DQP_7ADBC7A4.png"&gt;&lt;img style="border-width:0px;padding-top:0px;padding-right:0px;padding-left:0px;display:inline;background-image:none;" title="E08_DQP" border="0" alt="E08_DQP" src="http://blogs.adatis.co.uk/blogs/victormendes/E08_DQP_thumb_1E94EF3F.png" width="494" height="260" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The new synonyms will now be added to the existing KB domain values.&lt;/p&gt; &lt;a title="graphic48" name="graphic48"&gt;&lt;/a&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/victormendes/E09_DQP_6C311BBF.png"&gt;&lt;img style="border-width:0px;padding-top:0px;padding-right:0px;padding-left:0px;display:inline;background-image:none;" title="E09_DQP" border="0" alt="E09_DQP" src="http://blogs.adatis.co.uk/blogs/victormendes/E09_DQP_thumb_5DF2A2CF.png" width="473" height="309" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;This has been a simple example on how to train and retrain a new KB. By having a definitive list of counties the need to analyse our data prior to creating the KB is somewhat reduced. &lt;/p&gt;  &lt;p&gt;When building a KB it is important to acquire knowledge from samples of source data using any of the features available. From this example the output of a cleansing project provides a simpler method where the confidence level for suggested values is much lower. Once the KB contains sufficient knowledge for cleansing the confidence level can be increased and larger sets of data can be cleansed.&lt;/p&gt;  &lt;p&gt;DQS is a great tool for the power user to maintain content with little input from IT. In posts to follow I will also review Matching projects and the SSIS DQS component.&lt;/p&gt;&lt;img src="http://blogs.adatis.co.uk/aggbug.aspx?PostID=10133" width="1" height="1"&gt;</description><category domain="http://blogs.adatis.co.uk/blogs/victormendes/archive/tags/DQS/default.aspx">DQS</category><category domain="http://blogs.adatis.co.uk/blogs/victormendes/archive/tags/Data+Quality+Services/default.aspx">Data Quality Services</category><category domain="http://blogs.adatis.co.uk/blogs/victormendes/archive/tags/SQL+Server+2012/default.aspx">SQL Server 2012</category></item><item><title>Master Data Services in SQL Server 2012 RC0</title><link>http://blogs.adatis.co.uk/blogs/jeremykashel/archive/2011/11/30/master-data-services-in-sql-server-2012-rc0.aspx</link><pubDate>Wed, 30 Nov 2011 13:31:34 GMT</pubDate><guid isPermaLink="false">8d7d37f8-4a66-4c95-9fba-293fa87607dc:10075</guid><dc:creator>Jeremy Kashel</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;There’s been a whole host of changes to MDS in the &lt;a href="http://www.microsoft.com/download/en/details.aspx?id=28145&amp;amp;WT.mc_id=rss_alldownloads_all" target="_blank"&gt;SQL Server 2012 RC (Release Candidate) 0&lt;/a&gt; that came out the other week. This blog post gives an overview of the changes, before diving into detail on a few of them. At a high level, the following changes have been made to MDS:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Improved Master Data Manager front screen UI and navigation paths &lt;/li&gt;    &lt;li&gt;Collections interface updated to Silverlight &lt;/li&gt;    &lt;li&gt;Improved Excel user interface &amp;amp; functionality &lt;/li&gt;    &lt;li&gt;Auto generation of entity code values, without using business rules &lt;/li&gt;    &lt;li&gt;New deployment tool &lt;/li&gt;    &lt;li&gt;SharePoint integration &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Let’s take a look at each of these changes:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Improved Master Data Manager UI&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Although the UI improvement (shown below) is good, the best thing about the Master Data Manager changes, in my opinion, is that clicking on the Explorer feature no longer takes you into the Model View, but instead takes you straight into your master data for your core entity (e.g. in a Customer model this entity would be Customer). I’m not sure if this would get a bit frustrating if you didn’t want the core entity, but then again everything seems very quick in RC0, so I don’t think it’s really going to matter.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/jeremykashel/Front-screen_72D8B875.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="Front screen" border="0" alt="Front screen" src="http://blogs.adatis.co.uk/blogs/jeremykashel/Front-screen_thumb_17F602E2.png" width="355" height="359" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;There’s also a new button next to a domain-based attribute that apparently has been designed to &lt;a href="http://social.technet.microsoft.com/wiki/contents/articles/5648.aspx" target="_blank"&gt;help with Many-to-Many relationships&lt;/a&gt;. I can definitely see that working, but it’s useful to have anyway to jump to the member details for the domain based attribute that you are viewing, many-to-many or not:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/jeremykashel/image_0AAF79CF.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/jeremykashel/image_thumb_03240A62.png" width="352" height="90" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Collections Interface Updated to Silverlight&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;The collections interface is now much slicker, getting the Silverlight makeover seen in other areas of Master Data Manager. Switching between collections, for example, which could take a while in R2, now happens very quickly, making collections far more useable. The screen shot below shows how you edit collection members by picking members from one of the entities and adding those over into the collection by clicking the Add button:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/jeremykashel/image_1B4774BD.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/jeremykashel/image_thumb_32FEAC23.png" width="703" height="226" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Collections now have the concept of a Weight, meaning that you can alter the weighting value associated with the collection members, which could be useful for reporting purposes. The idea is that you extract the collection members and the weight values in a subscription view. A Weight column is actually included in the 2008 R2 collection subscription views, but there was no front end to modify the weight value, which has of course now changed:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/jeremykashel/image_09A76425.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/jeremykashel/image_thumb_170D772B.png" width="340" height="75" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Improved Excel User Interface and Functionality&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;The MDS Excel Ribbon has been given a makeover, meaning that you now see the following in the ribbon:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/jeremykashel/Excel-toolbar_5D1E343E.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="Excel toolbar" border="0" alt="Excel toolbar" src="http://blogs.adatis.co.uk/blogs/jeremykashel/Excel-toolbar_thumb_5B013575.png" width="721" height="121" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;It’s interesting to see that the Favourites section has been replaced with the concept of ‘queries’. The idea is that you can send a query file via email to another user, providing that user has the Excel add-in. When the user double clicks on the query file (extension *.mdsqx), Excel will open and make a connection to MDS, using the connection and filter information provided in the file. This will result in Excel opening, with the user prompted if they would like to connect to MDS:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/jeremykashel/confirm-connection_55EED1F9.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="confirm connection" border="0" alt="confirm connection" src="http://blogs.adatis.co.uk/blogs/jeremykashel/confirm-connection_thumb_6E123C54.png" width="266" height="143" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;It’s also good to see that a few of the domain-based attribute issues have been addressed, namely the display of domain-based attribute names when you filter an entity and also the display of the names and the codes together in the Excel sheet. Here’s a screen shot of the how the attribute names are now visible when filtering the Country domain-based attribute that exists in the Customer model:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/jeremykashel/image_5A84DCB3.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/jeremykashel/image_thumb_4BDA30CE.png" width="403" height="197" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Auto Generation of Entity Code Values&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;If you wanted the code to be auto-generated in 2008 R2, you had to use a business rule. You can still do that if you want, but the create entity admin screen has changed slightly to include an option to auto generate the code. This works slightly better than business rules in my opinion, at least as far as the Excel add-in is concerned, as the code is returned to the user immediately after publishing, whereas the business rules require you to do a refresh in Excel and of course need more development! Here’s a screenshot of the add entity screen:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/jeremykashel/image_7163AE2F.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/jeremykashel/image_thumb_49BD3205.png" width="267" height="206" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;New Deployment Tool&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Deployment has been altered in SQL 2012, with the addition of a &lt;a href="http://msdn.microsoft.com/en-us/library/ff486956(v=SQL.110).aspx" target="_blank"&gt;new deployment tool&lt;/a&gt;, plus the fact that subscription views now get deployed. It seems that the current R2 deployment method (in the Administration section of Master Data Manager) is still included but now will not deploy data. To do that you need to use MDSModelDeploy.exe, as explained &lt;a href="http://msdn.microsoft.com/en-us/library/hh479646(v=SQL.110).aspx" target="_blank"&gt;here&lt;/a&gt;. As an example, here’s how you can deploy the sample Customer model using MDSModelDeploy.exe, for default installations:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;MDSModelDeploy deploynew –package “C:\Program Files\Microsoft SQL Server\110\Master Data Services\Samples\customer_en.pkg” –model “Customer” –service “MDS1”&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;strong&gt;SharePoint Integration and Further Details&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Master Data Manager now supports a set of parameters that allow the MDS UI to be displayed without the header, menu bar and padding area. This means that MDS can now be incorporated into SharePoint or other websites. For the details on this, as well as more details on the above points, take a look at the following &lt;a href="http://social.technet.microsoft.com/wiki/contents/articles/5648.aspx" target="_blank"&gt;Technet article&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://blogs.adatis.co.uk/aggbug.aspx?PostID=10075" width="1" height="1"&gt;</description><category domain="http://blogs.adatis.co.uk/blogs/jeremykashel/archive/tags/MDM/default.aspx">MDM</category><category domain="http://blogs.adatis.co.uk/blogs/jeremykashel/archive/tags/Master+Data+Services/default.aspx">Master Data Services</category><category domain="http://blogs.adatis.co.uk/blogs/jeremykashel/archive/tags/MDS/default.aspx">MDS</category><category domain="http://blogs.adatis.co.uk/blogs/jeremykashel/archive/tags/Master+Data+Management/default.aspx">Master Data Management</category><category domain="http://blogs.adatis.co.uk/blogs/jeremykashel/archive/tags/SQL+Server+2012/default.aspx">SQL Server 2012</category></item><item><title>Working with Images in Power View</title><link>http://blogs.adatis.co.uk/blogs/jeremykashel/archive/2011/11/29/working-with-images-in-power-view.aspx</link><pubDate>Tue, 29 Nov 2011 13:04:31 GMT</pubDate><guid isPermaLink="false">8d7d37f8-4a66-4c95-9fba-293fa87607dc:10068</guid><dc:creator>Jeremy Kashel</dc:creator><slash:comments>1</slash:comments><description>&lt;p&gt;Power View includes several ways to create visualisations with images, ranging from a simple table, to the scrollable tile visualisation. In this post I’m going to explain a bit about the tile visualisation, showing how it can be used in Power View, before showing a couple of tips for working with images in both PowerPivot and Analysis Services Tabular models.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Power View Tiles&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;The Power View Tiles visualisation allows you to display a scrollable series of images, which, when clicked on, will display data of your choosing. The report below is an example of this:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/jeremykashel/image_41F4FB4E.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/jeremykashel/image_thumb_3AD5BED6.png" width="592" height="372" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;What’s nice about the View above is that the names of the products are automatically displayed underneath the images. This is a sensible place to display the product names, as it means the area below can focus on whatever product level data you want, in this case Revenue by Month for the selected product.&lt;/p&gt;  &lt;p&gt;This works fine in the sample models (in my case the Tailspin Toys model that I think came with CTP3) but it wont work in vanilla PowerPivot / Tabular models unless you configure a few model settings. Trying to reproduce the report above without these settings will give the following tile visualisation, minus the product names:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/jeremykashel/image_16B06447.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/jeremykashel/image_thumb_2FAC348C.png" width="362" height="132" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;PowerPivot Advanced Settings&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;To address this in PowerPivot, you first of all need to switch to Advanced Mode, which you can do by selecting this option from the File menu in PowerPivot:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/jeremykashel/image_1ABAB219.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/jeremykashel/image_thumb_48A804D1.png" width="244" height="193" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;This gives you the following advanced tab:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/jeremykashel/image_61A3D516.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/jeremykashel/image_thumb_0F9127CF.png" width="311" height="88" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Clicking on the highlighted Table Behaviour button in the ribbon gives you the following Table Behaviour window:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/jeremykashel/image_7A9FA55B.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/jeremykashel/image_thumb_288CF814.png" width="429" height="306" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Here you can “change the default behaviour for different visualisation types and default grouping behaviour in client tools for this table”. The following properties should be set in order to get the tiles working correctly:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;Row Identifier&lt;/strong&gt; – Specifies a column that only contains unique values, which allows the column to be used as an internal grouping key in client tools. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Default Label &lt;/strong&gt;– Specifies which column gives a row level display name, e.g. the product name in a Product table. This is key, as when a row level image is used, this property specifies which value to display alongside the image in tiles and other image-based visualisation. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Default Image&lt;/strong&gt; – Specifies which column contains images representing the row level data, e.g. pictures of products. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The full details for all these properties can be found &lt;a href="http://msdn.microsoft.com/en-us/library/hh560542(v=SQL.110).aspx" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Tabular Models&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Tabular Models contain the same properties, which can be edited when you open a tabular project in the new SQL Server Data Tools. The image below shows how the properties have been configured for the column in my model called Image:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/jeremykashel/image_4188C859.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/jeremykashel/image_thumb_6F761B11.png" width="202" height="289" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Back to Power View&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;If we now build a tile visualisation using the image column, we will see that we get the names of the products returned along with the image. It’s also worth noting that the Image and Product Name columns have now have an icon next to them, indicating that the field exhibits &lt;a href="http://technet.microsoft.com/en-us/library/hh231518(SQL.110).aspx" target="_blank"&gt;“row level” behaviour&lt;/a&gt;:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/jeremykashel/image_365F3E0F.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/jeremykashel/image_thumb_216DBB9C.png" width="483" height="185" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Finally, for some examples of what’s new in Power View SQL 2012 RC0 take a look at &lt;a href="http://blogs.msdn.com/b/sqlrsteamblog/archive/2011/11/17/what-s-new-in-power-view.aspx" target="_blank"&gt;this post&lt;/a&gt; on the Reporting Services Team Blog.&lt;/p&gt;&lt;img src="http://blogs.adatis.co.uk/aggbug.aspx?PostID=10068" width="1" height="1"&gt;</description><category domain="http://blogs.adatis.co.uk/blogs/jeremykashel/archive/tags/Analysis+Services/default.aspx">Analysis Services</category><category domain="http://blogs.adatis.co.uk/blogs/jeremykashel/archive/tags/PowerPivot/default.aspx">PowerPivot</category><category domain="http://blogs.adatis.co.uk/blogs/jeremykashel/archive/tags/BISM/default.aspx">BISM</category><category domain="http://blogs.adatis.co.uk/blogs/jeremykashel/archive/tags/Tabular/default.aspx">Tabular</category><category domain="http://blogs.adatis.co.uk/blogs/jeremykashel/archive/tags/SQL+Server+2012/default.aspx">SQL Server 2012</category><category domain="http://blogs.adatis.co.uk/blogs/jeremykashel/archive/tags/Power+View/default.aspx">Power View</category></item><item><title>SQL Server 2012 Running Totals</title><link>http://blogs.adatis.co.uk/blogs/martynbullerwell/archive/2011/11/16/sql-server-2012-running-totals.aspx</link><pubDate>Wed, 16 Nov 2011 15:48:19 GMT</pubDate><guid isPermaLink="false">8d7d37f8-4a66-4c95-9fba-293fa87607dc:10034</guid><dc:creator>Martyn Bullerwell</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;SQL server has sometimes come under fire with the Oracle vs SQL Server debate because of the lack of some of the more advanced (and less used) functionality that is outlined in the SQL ANSI standards.&amp;#160;&amp;#160; An example of this is Window Functions, which became an ANSI standard under the ANSI:2003 revision.&amp;#160; A Window function is an aggregate function that can be applied to a subset of a full set of data.&amp;#160; Now this can be achieved in current versions of SQL Server (2008 R2 and its predecessors), but not using Window Functions and therefore has a performance implication.&amp;#160; There are about 3 or 4 approaches to achieving a running total in SQL Server prior to the 2012 version, however none particularly elegant.&amp;#160; &lt;/p&gt;  &lt;p&gt;For my following example I will outline how to perform a running total using AdvertureWorks2008 sample data.&amp;#160; I will remind us of 1 of the method&amp;#39;s (probably the most common) of how we used to do running totals prior to SQL Server 2012, and then show how to do the same running total using a SQL Server 2012 Window Function.&amp;#160; To set the scene, we will be looking for a running total of Line Items for a given Order.&amp;#160; This may be kind of query you may wish to write to generate an invoice with a running total on it.&lt;/p&gt;  &lt;p&gt;To begin with lets look at the more traditional query: &lt;/p&gt;  &lt;p&gt;SELECT    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; A.SalesOrderID,     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; A.SalesOrderDetailID,     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; A.LineTotal,     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; SUM(B.LineTotal)     &lt;br /&gt;FROM     &lt;br /&gt;Sales.SalesOrderDetail&amp;#160; AS A     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; CROSS JOIN Sales.SalesOrderDetail AS B     &lt;br /&gt;WHERE     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; B.SalesOrderDetailID &amp;lt;= A.SalesOrderDetailID     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; AND     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; A.SalesOrderID = B.SalesOrderID     &lt;br /&gt;GROUP BY     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; A.SalesOrderID,     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; A.SalesOrderDetailID,     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; A.LineTotal     &lt;br /&gt;ORDER BY&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; A.SalesOrderID,     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; A.SalesOrderDetailID,     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; A.LineTotal &lt;/p&gt;  &lt;p&gt;This simply works by self joining up to certain point, so works fine for any data that can be ordered easily, as running totals usually are this method usually suffices. &lt;/p&gt;  &lt;p&gt;The following query uses the new Window function in SQL Server 2012:&amp;#160;&amp;#160; &lt;/p&gt;  &lt;p&gt;SELECT&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; SalesOrderID,&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; SalesOrderDetailID,&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; LineTotal,&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; SUM(LineTotal)&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; OVER&amp;#160;&amp;#160;&amp;#160;&amp;#160; (PARTITION BY&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; SalesOrderID&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ORDER BY&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; SalesOrderDetailID) AS OrderRunningTotal     &lt;br /&gt;FROM&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Sales.SalesOrderDetail     &lt;br /&gt;ORDER BY&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; SalesOrderID,&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; SalesOrderDetailID,     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; LineTotal&lt;/p&gt;  &lt;p&gt;You will instantly notice that the second query is far more elegant, and more simplistic to understand.&amp;#160; In short, in this query, we are telling SQL server to Sum the “Line Total” over an ordered partition of the data.&amp;#160; Both queries return the same result, however it becomes interesting when we look at the execution plans, relative to each other.&amp;#160; This is shown below (apologies for the size of these): &lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/martynbullerwell/image_5AC83C0A.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/martynbullerwell/image_thumb_610F1298.png" width="964" height="372" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;What is important to note that the second (bottom) plan is smaller, and simpler.&amp;#160; the other, very significant point is that the Query Cost (relative to batch) is a whopping 97% for the old method of running totals, meaning that the new Windowing Functions are far more efficient.&amp;#160; &lt;/p&gt;  &lt;p&gt;In summary, I believe that this is an example of where SQL server is becoming a firm competitor to some of its perceived rivals, its one of the few points that can be raised as a valid point in the argument of SQL Server vs Oracle, but not any more! &lt;/p&gt;&lt;img src="http://blogs.adatis.co.uk/aggbug.aspx?PostID=10034" width="1" height="1"&gt;</description><category domain="http://blogs.adatis.co.uk/blogs/martynbullerwell/archive/tags/Denali/default.aspx">Denali</category><category domain="http://blogs.adatis.co.uk/blogs/martynbullerwell/archive/tags/SQl+Server+2012/default.aspx">SQl Server 2012</category><category domain="http://blogs.adatis.co.uk/blogs/martynbullerwell/archive/tags/Window+Function/default.aspx">Window Function</category></item><item><title>SQL Server 2012 : Columnstore Index in action</title><link>http://blogs.adatis.co.uk/blogs/sachatomey/archive/2011/11/09/sql-server-2012-columnstore-index-in-action.aspx</link><pubDate>Wed, 09 Nov 2011 16:17:40 GMT</pubDate><guid isPermaLink="false">8d7d37f8-4a66-4c95-9fba-293fa87607dc:10015</guid><dc:creator>sachatomey</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;One of the new SQL Server 2012 data warehouse features is the Columnstore index. It stores data by columns instead of by rows, similar to a column-oriented DBMS like the Vertica Analytic Database and claims to increase query performance by hundreds to thousands of times.&lt;/p&gt;  &lt;p&gt;The issue with indexes in a data warehouse environment is the number and broad range of questions that the warehouse may have to answer meaning you either have to introduce a large number of large indexes (that in many cases results in a larger set of indexes than actual data), plump for a costly spindle-rich hardware infrastructure, or you opt for a balanced hardware and software solution such as a &lt;a href="http://www.microsoft.com/sqlserver/en/us/solutions-technologies/data-warehousing/fast-track.aspx" target="_blank"&gt;Microsoft SQL Server 2008 R2 Fast Track Data Warehouse&lt;/a&gt; or a &lt;a href="http://www.microsoft.com/sqlserver/en/us/solutions-technologies/appliances/hp-bdw.aspx" target="_blank"&gt;HP Business Data Warehouse Appliance&lt;/a&gt; where the approach is ‘index-light’ and you rely on the combination of high throughput and performance power to reduce the dependency on the traditional index.&lt;/p&gt;  &lt;p&gt;The Columnstore index is different in that, when applied correctly, a broad range of questions can benefit from a single Columnstore index, the index is compressed (using the same Vertipaq technology that PowerPivot and Tabular based Analysis Services share) reducing the effort required on the expensive and slow disk subsystem and increasing the effort of the fast and lower cost memory/processor combination.&lt;/p&gt;  &lt;p&gt;In order to test the claims of the Columnstore index I’ve performed some testing on a Hyper-V instance of SQL Server 2012 “Denali” CTP3 using a blown up version of the AdventureWorksDWDenali sample database. I’ve increased the FactResellerSales table from approximately 61,000 records to approximately 15.5 million records and removed all existing indexes to give me a simple, but reasonably large ‘heap’. &lt;/p&gt;  &lt;h4&gt;Heap&lt;/h4&gt;  &lt;p&gt;With a clear cache, run the following simple aggregation:&lt;/p&gt;  &lt;p style="line-height:normal;margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;/p&gt;  &lt;p style="line-height:normal;margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;font face="Consolas"&gt;&lt;span style="font-family:;color:;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;mso-fareast-language:en-gb;mso-ansi-language:en;"&gt;&lt;font style="font-size:9.5pt;" color="#008080"&gt;&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Consolas"&gt;&lt;font color="#0000ff"&gt;SELECT&lt;/font&gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font color="#4bacc6"&gt;SalesTerritoryKey        &lt;br /&gt;&lt;/font&gt;&amp;#160;&amp;#160;&amp;#160; ,&lt;font color="#9b00d3"&gt;SUM&lt;/font&gt;(&lt;font color="#4bacc6"&gt;SalesAmount&lt;/font&gt;) &lt;font color="#0000ff"&gt;AS&lt;/font&gt; &lt;font color="#4bacc6"&gt;SalesAmount&lt;/font&gt;       &lt;br /&gt;&lt;font color="#0000ff"&gt;FROM&lt;/font&gt;       &lt;br /&gt;&amp;#160;&amp;#160; &lt;font color="#4bacc6"&gt; &lt;/font&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font color="#4bacc6"&gt;[AdventureWorksDWDenali].[dbo].[FactResellerSales]        &lt;br /&gt;&lt;/font&gt;&lt;font color="#0000ff"&gt;GROUP&lt;/font&gt;&lt;font color="#0000ff"&gt; BY&lt;/font&gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font color="#4bacc6"&gt;SalesTerritoryKey        &lt;br /&gt;&lt;/font&gt;&lt;font color="#0000ff"&gt;ORDER BY&lt;/font&gt;&amp;#160; &lt;br /&gt;&lt;font color="#4bacc6"&gt;&lt;font color="#000000"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;SalesTerritoryKey&lt;/font&gt;&lt;/font&gt; &lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/sachatomey/clip_image0014_thumb_thumb1_204F301F.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="clip_image0014_thumb_thumb[1]" border="0" alt="clip_image0014_thumb_thumb[1]" src="http://blogs.adatis.co.uk/blogs/sachatomey/clip_image0014_thumb_thumb1_thumb_66CC2027.png" width="240" height="223" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Consolas"&gt;Table &amp;#39;FactResellerSales&amp;#39;. Scan count 5, logical reads &lt;font style="background-color:#ffff00;"&gt;457665&lt;/font&gt;, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.       &lt;br /&gt;SQL Server Execution Times:       &lt;br /&gt;CPU time = 7641 ms, elapsed time = &lt;font style="background-color:#ffff00;"&gt;43718&lt;/font&gt; ms      &lt;br /&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;     &lt;br /&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/sachatomey/image_3C509B2D.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/sachatomey/image_thumb_261A7FDB.png" width="704" height="89" /&gt;&lt;/a&gt;&lt;/font&gt;&lt;/p&gt;  &lt;h4&gt;Non-Clustered Index&lt;/h4&gt;  &lt;p&gt;Before jumping straight in with a columnstore index, let’s review performance using a traditional index. I tried a variety of combinations, the fastest I could get this query to go was to simply add the following:&lt;/p&gt;  &lt;p&gt;&lt;font face="Consolas"&gt;&lt;font color="#0000ff"&gt;CREATE NONCLUSTERED INDEX&lt;/font&gt;&lt;font color="#4bacc6"&gt; [IX_SalesTerritoryKey]&lt;/font&gt; &lt;font color="#0000ff"&gt;ON&lt;/font&gt; [&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font color="#4bacc6"&gt;dbo].[FactResellerSales]        &lt;br /&gt;&lt;/font&gt;(       &lt;br /&gt;&amp;#160;&amp;#160; &lt;font color="#4bacc6"&gt;[SalesTerritoryKey]&lt;/font&gt; &lt;font color="#0000ff"&gt;ASC&lt;/font&gt;       &lt;br /&gt;)       &lt;br /&gt;&lt;font color="#0000ff"&gt;INCLUDE&lt;/font&gt; (&lt;font color="#4bacc6"&gt;[SalesAmount]&lt;/font&gt;) &lt;font color="#0000ff"&gt;WITH&lt;/font&gt;       &lt;br /&gt;(       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;font color="#0000ff"&gt;PAD_INDEX&lt;/font&gt; = &lt;font color="#0000ff"&gt;OFF&lt;/font&gt;, &lt;font color="#0000ff"&gt;STATISTICS_NORECOMPUTE&lt;/font&gt; = &lt;font color="#0000ff"&gt;OFF&lt;/font&gt;, &lt;font color="#0000ff"&gt;SORT_IN_TEMPDB&lt;/font&gt; = &lt;font color="#0000ff"&gt;OFF&lt;/font&gt;,       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font color="#0000ff"&gt;DROP_EXISTING &lt;font color="#000000"&gt;=&lt;/font&gt; OFF, ONLINE &lt;font color="#000000"&gt;=&lt;/font&gt; OFF, ALLOW_ROW_LOCKS &lt;font color="#000000"&gt;=&lt;/font&gt; ON,         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ALLOW_PAGE_LOCKS &lt;font color="#000000"&gt;=&lt;/font&gt; ON, FILLFACTOR &lt;font color="#000000"&gt;=&lt;/font&gt; 100, DATA_COMPRESSION &lt;font color="#000000"&gt;=&lt;/font&gt; PAGE&lt;/font&gt;       &lt;br /&gt;) &lt;font color="#0000ff"&gt;ON&lt;/font&gt; [PRIMARY]       &lt;br /&gt;&lt;font color="#0000ff"&gt;GO&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Notice I have compressed the index using page compression, this reduced the number of pages my data consumed significantly. The IO stats when I re-ran the same query (on a clear cache) looked like this:    &lt;br /&gt;    &lt;br /&gt;&lt;font face="Consolas"&gt;Table &amp;#39;FactResellerSales&amp;#39;. Scan count 5, logical reads &lt;font style="background-color:#ffff00;"&gt;26928&lt;/font&gt;, physical reads 0, read-ahead reads 26816, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.       &lt;br /&gt;SQL Server Execution Times:       &lt;br /&gt;CPU time = 6170 ms, elapsed time = &lt;font style="background-color:#ffff00;"&gt;5201&lt;/font&gt; ms.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/sachatomey/image_0CB27CA1.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/sachatomey/image_thumb_0C4649AC.png" width="704" height="89" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Much better! Approximately 6% of the original logical reads were required, resulting in a query response time of just over 5 seconds. Remember though, this new index will really only answer this specific question. If we change the query, performance is likely to fall off the cliff and revert back to the table scan.&lt;/p&gt;  &lt;p&gt;Incidentally, adopting an index-light ([no index]) approach and simply compressing (and reloading to remove fragmentation) the underlying table itself, performance was only nominally slower than the indexed table with the added advantage of being able to perform for a large number of different queries. (Effectively speeding up the table scan. Partitioning the table can help with this approach too.)&lt;/p&gt;  &lt;h4&gt;Columnstore Index&lt;/h4&gt;  &lt;p&gt;Okay, time to bring out the columnstore. The recommendation is to add all columns into the columnstore index (Columnstore indexes do not support ‘include’ columns), practically there may be a few cases where you do exclude some columns. Meta data, or system columns that are unlikely to be used in true analysis are good candidates to leave out of the columnstore. However, in this instance, I am including all columns:&lt;/p&gt;  &lt;p&gt;&lt;font face="Consolas"&gt;&lt;font color="#0000ff"&gt;CREATE NONCLUSTERED&lt;/font&gt; &lt;font color="#4bacc6"&gt;COLUMNSTORE&lt;/font&gt; &lt;font color="#0000ff"&gt;INDEX&lt;/font&gt; &lt;font color="#4bacc6"&gt;[IX_Columnstore] &lt;font color="#0000ff"&gt;ON&lt;/font&gt; [dbo].[FactResellerSales]         &lt;br /&gt;&lt;/font&gt;(       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;font color="#4bacc6"&gt;[ProductKey],        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; [OrderDateKey],         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; [DueDateKey],         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; [ShipDateKey],         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; [ResellerKey],         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; [EmployeeKey],         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; [PromotionKey],         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; [CurrencyKey],         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; [SalesTerritoryKey],         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; [SalesOrderNumber],         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; [SalesOrderLineNumber],         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; [RevisionNumber],         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; [OrderQuantity],         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; [UnitPrice],         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; [ExtendedAmount],         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; [UnitPriceDiscountPct],         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; [DiscountAmount],         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; [ProductStandardCost],         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; [TotalProductCost],         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; [SalesAmount],         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; [TaxAmt],         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; [Freight],         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; [CarrierTrackingNumber],         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; [CustomerPONumber],         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; [OrderDate],         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; [DueDate],         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; [ShipDate]         &lt;br /&gt;&lt;/font&gt;)&lt;font color="#0000ff"&gt;WITH&lt;/font&gt; (&lt;font color="#0000ff"&gt;DROP_EXISTING &lt;font color="#000000"&gt;=&lt;/font&gt; OFF&lt;/font&gt;) &lt;font color="#0000ff"&gt;ON&lt;/font&gt; [&lt;font color="#4bacc6"&gt;PRIMARY&lt;/font&gt;]&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Now when I run the query on a clear cache:&lt;/p&gt;  &lt;p&gt;&lt;font face="Consolas"&gt;Table &amp;#39;FactResellerSales_V2&amp;#39;. Scan count 4, logical reads &lt;font style="background-color:#ffff00;"&gt;2207&lt;/font&gt;, physical reads 18, read-ahead reads 3988, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.       &lt;br /&gt;SQL Server Execution Times:       &lt;br /&gt;CPU time = 235 ms, elapsed time = &lt;font style="background-color:#ffff00;"&gt;327&lt;/font&gt; ms.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/sachatomey/image_1D915F15.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/sachatomey/image_thumb_4B127ED8.png" width="704" height="89" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;I think the figures speak for themselves ! Sub-second response and because all columns are part of the index, a broad range of questions can be satisfied by this single index.&lt;/p&gt;  &lt;h4&gt;Storage&lt;/h4&gt;  &lt;p&gt;The traditional (compressed) non-clustered index takes up around &lt;strong&gt;208 MB&lt;/strong&gt; whereas the Columnstore Index comes in a little less at &lt;strong&gt;194 MB&lt;/strong&gt; so speed and storage efficiency, further compounded when you take into account the potential additional indexes the warehouse may require. &lt;/p&gt;  &lt;p&gt;So, the downsides? Columnstore indexes render the table read-only. In order to to update the table you either need to drop and re-create the index or employ a partition switching approach. The other notable disadvantage, consistently witnessed during my tests, is the columnstore index takes longer to build. The traditional non-clustered index took approximately 21 seconds to build whereas the columnstore took approximately 1 minute 49 seconds. Remember though, you only need one columnstore index to satisfy many queries so that’s potentially not a fair comparison.&lt;/p&gt;  &lt;h4&gt;Troubleshooting&lt;/h4&gt;  &lt;p&gt;If you don’t notice a huge difference between a table scan and a Columnstore Index Scan, check the &lt;b&gt;Actual Execution Mode &lt;/b&gt;of the Columnstore Index Scan. This should be set to Batch, not Row.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/sachatomey/image_6ED2FC80.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/sachatomey/image_thumb_06F666DC.png" width="444" height="134" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/sachatomey/image_589CE12E.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/sachatomey/image_thumb_0D3D3D6A.png" width="444" height="132" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;If the Actual Execution Mode is reporting Row then your query cannot run in parallel:&lt;/p&gt;  &lt;p&gt;- Ensure, if running via Hyper-V, you have assigned more than one processor to the image.    &lt;br /&gt;- Ensure the Server Property ‘Max Degee of Parallelism’ is not set to 1.&lt;/p&gt;  &lt;h4&gt;Summary&lt;/h4&gt; In summary, for warehousing workloads, a columnstore index is a great addition to the database engine with significant performance improvements even on reasonably small data sets. It will re-define the ‘index-light’ approach that the SQL Server Fast Track Data Warehouse methodology champions and help simplify warehouse based performance tuning activities. Will it work in every scenario? I very much doubt it, but it’s a good place to start until we get to experience it live in the field.              &lt;img src="http://blogs.adatis.co.uk/aggbug.aspx?PostID=10015" width="1" height="1"&gt;</description><category domain="http://blogs.adatis.co.uk/blogs/sachatomey/archive/tags/Business+Intelligence/default.aspx">Business Intelligence</category><category domain="http://blogs.adatis.co.uk/blogs/sachatomey/archive/tags/Fast+Track/default.aspx">Fast Track</category><category domain="http://blogs.adatis.co.uk/blogs/sachatomey/archive/tags/Data+Warehouse/default.aspx">Data Warehouse</category><category domain="http://blogs.adatis.co.uk/blogs/sachatomey/archive/tags/Appliance/default.aspx">Appliance</category><category domain="http://blogs.adatis.co.uk/blogs/sachatomey/archive/tags/BDW/default.aspx">BDW</category><category domain="http://blogs.adatis.co.uk/blogs/sachatomey/archive/tags/SQL+Server+2012/default.aspx">SQL Server 2012</category><category domain="http://blogs.adatis.co.uk/blogs/sachatomey/archive/tags/Warehouse/default.aspx">Warehouse</category><category domain="http://blogs.adatis.co.uk/blogs/sachatomey/archive/tags/Columnstore/default.aspx">Columnstore</category><category domain="http://blogs.adatis.co.uk/blogs/sachatomey/archive/tags/Tuning/default.aspx">Tuning</category></item><item><title>Managing SSAS Named Sets with Master Data Services Collections</title><link>http://blogs.adatis.co.uk/blogs/jeremykashel/archive/2011/11/07/managing-ssas-named-sets-with-master-data-services-collections.aspx</link><pubDate>Mon, 07 Nov 2011 17:04:00 GMT</pubDate><guid isPermaLink="false">8d7d37f8-4a66-4c95-9fba-293fa87607dc:10006</guid><dc:creator>Jeremy Kashel</dc:creator><slash:comments>2</slash:comments><description>&lt;p&gt;Master Data Services &lt;a href="http://msdn.microsoft.com/en-us/library/ee633733.aspx" target="_blank"&gt;Collections&lt;/a&gt; are probably not the first feature that come to mind when you think of the MDS product. The hierarchies and member grids tend to be the core functionality, but as this post will hopefully show, MDS Collections are useful also.&lt;/p&gt;  &lt;p&gt;Collections are essentially managed lists of members that can come from multiple different MDS explicit hierarchies, or also from another collection. The idea is that this “subset of members” can be maintained in MDS by a business user and then fed to external applications for reporting or other purposes.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Analysis Services Named Sets&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;One example of how collections can be used is to maintain Analysis Services named sets. Some named sets, such as a Top 50 Customers, don&amp;#39;t require any maintenance, as it’s just the top 50 of all customers, based on a particular measure. On the other hand, sometimes named sets can be static lists, e.g. a list of core products that the user wants to see for reporting.&lt;/p&gt;  &lt;p&gt;In the latter example, if a user wants the definition of a named set to change, they have to get IT to change the MDX script. MDS collections can help by allowing the user to control the named set definition, reducing the burden on IT.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Example Scenario&lt;/strong&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;Here’s an example of how this is done. First of all, the end game is that I have a named set in Analysis Services that is currently just for 3 products. Therefore, a user can easily drop this set into an Excel report to get quick access to the products that are important to them:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/jeremykashel/image_3AD09CE1.png"&gt;&lt;img style="border:0px currentColor;padding-top:0px;padding-right:0px;padding-left:0px;display:inline;background-image:none;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/jeremykashel/image_thumb_6132802C.png" width="343" height="114" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;So the challenge is that we need to find some way of extending this named set without doing it manually. This is where MDS starts to come in, so using the sample Product model that comes with MDS, I’ve created a new collection called Favourite Products, as shown in the image below:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/jeremykashel/image_0008F40B.png"&gt;&lt;img style="border:0px currentColor;padding-top:0px;padding-right:0px;padding-left:0px;display:inline;background-image:none;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/jeremykashel/image_thumb_033ADBF3.png" width="454" height="173" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;If I go and edit the Favourite Products collection in MDS, then I can drag and drop more products into this collection, or remove some existing members. In this case, I’ve chosen to add two new products:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/jeremykashel/image_01F64314.png"&gt;&lt;img style="border:0px currentColor;padding-top:0px;padding-right:0px;padding-left:0px;display:inline;background-image:none;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/jeremykashel/image_thumb_1D2E9C15.png" width="380" height="172" /&gt;&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;&lt;strong&gt;C#, AMO and the MDS API&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;So the named set represents the target that we need to get to, whereas the MDS collection that’s shown is the source. To get the contents of the MDS collection to update the named set, one way of doing it is to use the MDS API to pick up the collection members, and then to use AMO in order to write the named set into the MDX script. I’m just doing this in a C# windows application, but you could do it via a batch process, such as SSIS. For this post I’m just going to show the code, so here goes:&lt;/p&gt;  &lt;p&gt;This post is already starting to feel too long so I’m not going to show the basics of the MDS API. For that, take a look at a good posting by the MDS Team blog &lt;a href="http://sqlblog.com/blogs/mds_team/archive/2010/01/12/getting-started-with-the-web-services-api-in-sql-server-2008-r2-master-data-services.aspx" target="_blank"&gt;here&lt;/a&gt;. Also, as anyone who knows me will no doubt agree, I don’t tend to get involved in doing C#, so don’t consider this to be production ready! It should give you an idea of the basics though. Anyway, assuming that we’re now connected to the MDS Web Service, I’ve created the following method that will return the members from the collection:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;private &lt;/span&gt;&lt;span&gt;HierarchyMembers &lt;/span&gt;ObtainHierarchyMembers(&lt;span style="color:blue;"&gt;string &lt;/span&gt;entityId, &lt;span style="color:blue;"&gt;string &lt;/span&gt;hierarchyId, &lt;span style="color:blue;"&gt;string &lt;/span&gt;modelId, &lt;span style="color:blue;"&gt;string &lt;/span&gt;versionId)
{
    &lt;span&gt;HierarchyMembersGetRequest &lt;/span&gt;request = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span&gt;HierarchyMembersGetRequest&lt;/span&gt;();
    &lt;span&gt;HierarchyMembersGetResponse &lt;/span&gt;response = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span&gt;HierarchyMembersGetResponse&lt;/span&gt;();
    request.HierarchyMembersGetCriteria = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span&gt;HierarchyMembersGetCriteria&lt;/span&gt;();

    &lt;span style="color:green;"&gt;//State that our hierarhcy type is a collection and that we want collection members
    &lt;/span&gt;request.HierarchyMembersGetCriteria.HierarchyType = &lt;span&gt;HierarchyType&lt;/span&gt;.Collection;
    &lt;span style="color:green;"&gt;//Pass in the key search criteria to identify the correct collection in MDS
    &lt;/span&gt;request.HierarchyMembersGetCriteria.ParentEntityId = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span&gt;Identifier &lt;/span&gt;{ Name = entityId };
    request.HierarchyMembersGetCriteria.HierarchyId = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span&gt;Identifier &lt;/span&gt;{ Name = hierarchyId };
    request.HierarchyMembersGetCriteria.ModelId = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span&gt;Identifier &lt;/span&gt;{ Name = modelId };
    request.HierarchyMembersGetCriteria.VersionId = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span&gt;Identifier &lt;/span&gt;{ Name = versionId };

    request.HierarchyMembersGetCriteria.RowLimit = 50;
    request.International = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span&gt;International&lt;/span&gt;();
    &lt;span&gt;OperationResult &lt;/span&gt;result = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span&gt;OperationResult&lt;/span&gt;();
    &lt;span style="color:green;"&gt;//Return the hierarchy members from the service
    &lt;/span&gt;&lt;span style="color:blue;"&gt;return &lt;/span&gt;service.HierarchyMembersGet(request.International, request.HierarchyMembersGetCriteria, &lt;span style="color:blue;"&gt;out &lt;/span&gt;result);
}&lt;/pre&gt;

&lt;p&gt;Before we use the above method, we need to connect to SSAS using AMO. That can be done quite easily with the following code:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span&gt;Server &lt;/span&gt;server = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span&gt;Server&lt;/span&gt;();
&lt;span style="color:blue;"&gt;string &lt;/span&gt;connection = &lt;span&gt;&amp;quot;Data Source=.;Catalog=Adventure Works DW 2008R2;&amp;quot;&lt;/span&gt;;
server.Connect(connection);&lt;/pre&gt;

&lt;p&gt;After we’ve done all the usual error handling associated with connecting to a database, we need to pick up the SSAS database and cube:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span&gt;Database &lt;/span&gt;database = server.Databases[&lt;span&gt;&amp;quot;Adventure Works DW 2008R2&amp;quot;&lt;/span&gt;];
&lt;span&gt;Cube &lt;/span&gt;cube = database.Cubes[&lt;span&gt;&amp;quot;Adventure Works&amp;quot;&lt;/span&gt;];&lt;/pre&gt;

&lt;p&gt;Now we’re ready to call our ObtainHierarchyMembers method, before looping through it to build the named set:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span&gt;StringBuilder &lt;/span&gt;mdx = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span&gt;StringBuilder&lt;/span&gt;(&lt;span&gt;&amp;quot;\n//Auto generated named set at &amp;quot; &lt;/span&gt;+ &lt;span&gt;DateTime&lt;/span&gt;.Now.ToString() + 
    &lt;span&gt;&amp;quot;\nCREATE SET CurrentCube.[Favourite Products] AS {&amp;quot;&lt;/span&gt;);
&lt;span style="color:blue;"&gt;int &lt;/span&gt;count = 1;
&lt;span style="color:green;"&gt;//Loop through the collection to build the mdx
&lt;/span&gt;&lt;span style="color:blue;"&gt;foreach &lt;/span&gt;(&lt;span&gt;ParentChild &lt;/span&gt;pc &lt;span style="color:blue;"&gt;in &lt;/span&gt;hm.Members)
{
    &lt;span style="color:green;"&gt;//Add the members to the MDX string
    //This references the member by name
    //It would be possible to reference by member key, but would require more work
    &lt;/span&gt;mdx.Append(&lt;span&gt;&amp;quot;[Product].[Product].[&amp;quot; &lt;/span&gt;+ pc.Child.Name + &lt;span&gt;&amp;quot;]&amp;quot;&lt;/span&gt;);
    &lt;span style="color:blue;"&gt;if &lt;/span&gt;(count &amp;lt; hm.Members.Count())
    {
        mdx.Append(&lt;span&gt;&amp;quot;, &amp;quot;&lt;/span&gt;);
    }
    count++;
}
mdx.Append(&lt;span&gt;&amp;quot;};&amp;quot;&lt;/span&gt;);&lt;/pre&gt;


&lt;p&gt;Now we need to insert the named set in the correct place within the existing MDX script, bearing in mind it could already exist:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;string &lt;/span&gt;currentScript = cube.MdxScripts[0].Commands[0].Text;
&lt;span style="color:green;"&gt;//Find the correct place to insert the named set within the MDX script:
&lt;/span&gt;&lt;span style="color:blue;"&gt;int &lt;/span&gt;start = currentScript.IndexOf(&lt;span&gt;&amp;quot;\n//Auto generated named set at&amp;quot;&lt;/span&gt;);
&lt;span style="color:blue;"&gt;int &lt;/span&gt;end = 0;
&lt;span&gt;StringBuilder &lt;/span&gt;newScript = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span&gt;StringBuilder&lt;/span&gt;(currentScript);
&lt;span style="color:blue;"&gt;if &lt;/span&gt;(start != -1)
{
    end = currentScript.IndexOf(&lt;span&gt;&amp;quot;;&amp;quot;&lt;/span&gt;, start);
    &lt;span style="color:green;"&gt;//If the named set already exists, remove it
    &lt;/span&gt;newScript.Remove(start, end - start + 1);
}
&lt;span style="color:blue;"&gt;else
&lt;/span&gt;{
    start = currentScript.Length;
}
&lt;span style="color:green;"&gt;//Insert the named set in the correct place
&lt;/span&gt;newScript.Insert(start, mdx.ToString());
&lt;span style="color:green;"&gt;//Update the cube&amp;#39;s MDX script
&lt;/span&gt;cube.MdxScripts[0].Commands[0].Text = newScript.ToString();&lt;/pre&gt;

&lt;p&gt;Finally we just need to update the cube in order to write the MDX back to the cube:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:green;"&gt;//Call the update methods to update the cube
&lt;/span&gt;cube.MdxScripts[0].Update();
cube.Update();&lt;/pre&gt;




&lt;p&gt;&lt;strong&gt;User Reports&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now that the cube has been updated, if the Excel report is refreshed, then the two new products will appear in the list:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/jeremykashel/image_06F880C3.png"&gt;&lt;img style="border:0px currentColor;padding-top:0px;padding-right:0px;padding-left:0px;display:inline;background-image:none;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/jeremykashel/image_thumb_145E93C9.png" width="348" height="150" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Summary&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Controlling SSAS named sets like this won’t be for everybody. I’ve certainly worked in a few clients where strict process has to be followed to update this sort of thing, but I can think of other companies that I know where this would be really useful.&lt;/p&gt;

&lt;p&gt;Managing Analysis Services named sets is just one use for collections. Another example might be managing default multi-select parameters for SSRS reports. As collections are just lists of members that can be extracted easily, what you do with them is up to you!&lt;/p&gt;&lt;img src="http://blogs.adatis.co.uk/aggbug.aspx?PostID=10006" width="1" height="1"&gt;</description><category domain="http://blogs.adatis.co.uk/blogs/jeremykashel/archive/tags/MDX/default.aspx">MDX</category><category domain="http://blogs.adatis.co.uk/blogs/jeremykashel/archive/tags/Analysis+Services/default.aspx">Analysis Services</category><category domain="http://blogs.adatis.co.uk/blogs/jeremykashel/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.adatis.co.uk/blogs/jeremykashel/archive/tags/MDM/default.aspx">MDM</category><category domain="http://blogs.adatis.co.uk/blogs/jeremykashel/archive/tags/Master+Data+Services/default.aspx">Master Data Services</category><category domain="http://blogs.adatis.co.uk/blogs/jeremykashel/archive/tags/MDS/default.aspx">MDS</category><category domain="http://blogs.adatis.co.uk/blogs/jeremykashel/archive/tags/Master+Data+Management/default.aspx">Master Data Management</category></item><item><title>SQL Server 2012 Licensing</title><link>http://blogs.adatis.co.uk/blogs/sachatomey/archive/2011/11/03/sql-server-2012-licensing.aspx</link><pubDate>Thu, 03 Nov 2011 16:48:00 GMT</pubDate><guid isPermaLink="false">8d7d37f8-4a66-4c95-9fba-293fa87607dc:9994</guid><dc:creator>sachatomey</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;Today saw the announcement of how SQL Server 2012 will be carved up and licensed, and it&amp;#39;s changed quite a bit. There are three key changes:&lt;/p&gt;  &lt;p&gt;1) There&amp;#39;s a new Business Intelligence Edition that sits between Standard and Enterprise    &lt;br /&gt;2) No more processor licensing. There&amp;#39;s a move to Core based licensing instead (with a minimum cost of 4 cores per server)     &lt;br /&gt;3) Enterprise is only available on the Core licensing model (Unless upgrading through Software Assurance *)&lt;/p&gt;  &lt;p&gt;Enterprise, as you would expect, has all the functionality SQL Server 2012 has to offer. &lt;/p&gt;  &lt;p&gt;The Business Intelligence edition strips away    &lt;br /&gt;- Advanced Security &lt;em&gt;(Advanced auditing, transparent data encryption)      &lt;br /&gt;- &lt;/em&gt;Data Warehousing &lt;em&gt;(ColumnStore, compression, partitioning)&lt;/em&gt;     &lt;br /&gt;and provides a cut-down, basic (as opposed to advanced) level of High Availability &lt;em&gt;(AlwaysOn). &lt;/em&gt;&lt;/p&gt;  &lt;p&gt;In addition, the Standard Edition removes    &lt;br /&gt;- Enterprise data management (Data Quality Services, Master Data Services),     &lt;br /&gt;- Self-Service Business Intelligence (Power View, PowerPivot for SPS)     &lt;br /&gt;- Corporate Business Intelligence (Semantic model, advanced analytics)&lt;/p&gt;  &lt;p&gt;If you are utilising 4 core processors, licence costs for Standard ($1,793 per core, or $898 per Server + $209 per CAL) and Enterprise ($6,874 per core) remain similar (ish).&amp;#160; However, you will be stung if you have more cores. The Business Intelligence edition is only available via a Server + CAL licence model and it&amp;#39;s apparent that Microsoft are placing a big bet on MDS/DQS, Power View, PowerPivot for SharePoint and BISM as the licence for the Business Intelligence edition is $8,592 per server, plus $209 per CAL, that&amp;#39;s nearly 10x more per server than Standard Edition !&lt;/p&gt;  &lt;p&gt;For the complete low-down check out these links:&lt;/p&gt;  &lt;p&gt;Editions Overview:    &lt;br /&gt;&lt;a href="http://www.microsoft.com/sqlserver/en/us/future-editions/sql2012-editions.aspx"&gt;http://www.microsoft.com/sqlserver/en/us/future-editions/sql2012-editions.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Licensing Overview:    &lt;br /&gt;&lt;a href="http://www.microsoft.com/sqlserver/en/us/future-editions/sql2012-licensing.aspx"&gt;http://www.microsoft.com/sqlserver/en/us/future-editions/sql2012-licensing.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Licence Detail (including costs):    &lt;br /&gt;&lt;a href="http://download.microsoft.com/download/D/A/D/DADBE8BD-D5C7-4417-9527-5E9A717D8E84/SQLServer2012_Licensing_Datasheet_Nov2011.docx"&gt;http://download.microsoft.com/download/D/A/D/DADBE8BD-D5C7-4417-9527-5E9A717D8E84/SQLServer2012_Licensing_Datasheet_Nov2011.docx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;* If you are currently running Enterprise as a Server + CAL and you upgrade to SQL 2012 through Software Assurance, you can keep Server + CAL model, providing you don’t exceed 20 cores.&lt;/p&gt;&lt;img src="http://blogs.adatis.co.uk/aggbug.aspx?PostID=9994" width="1" height="1"&gt;</description><category domain="http://blogs.adatis.co.uk/blogs/sachatomey/archive/tags/Business+Intelligence/default.aspx">Business Intelligence</category><category domain="http://blogs.adatis.co.uk/blogs/sachatomey/archive/tags/Data+Warehouse/default.aspx">Data Warehouse</category><category domain="http://blogs.adatis.co.uk/blogs/sachatomey/archive/tags/Licensing/default.aspx">Licensing</category><category domain="http://blogs.adatis.co.uk/blogs/sachatomey/archive/tags/SQL+Server+2012/default.aspx">SQL Server 2012</category><category domain="http://blogs.adatis.co.uk/blogs/sachatomey/archive/tags/Warehouse/default.aspx">Warehouse</category></item><item><title>Master Data Services Training in the UK</title><link>http://blogs.adatis.co.uk/blogs/jeremykashel/archive/2011/11/01/sql-server-training-in-london.aspx</link><pubDate>Tue, 01 Nov 2011 23:33:00 GMT</pubDate><guid isPermaLink="false">8d7d37f8-4a66-4c95-9fba-293fa87607dc:9986</guid><dc:creator>Jeremy Kashel</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;This is just a quick post to announce a range of SQL Server training courses, organised (and in some cases delivered) by &lt;a href="http://cwebbbi.wordpress.com/" target="_blank"&gt;Chris Webb&lt;/a&gt;. To start off there’s a SQL Server course delivered by Christian Bolton in December, followed by an Analysis Services course delivered by Chris in February. I’ll be delivering a Master Data Services course in February, before Chris delivers an MDX course in March.&lt;/p&gt;  &lt;p&gt;The details for all the courses are:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;SQL Server Internals and Troubleshooting Workshop - Christian Bolton – 6th – 7th December 2011&lt;/strong&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;blockquote&gt;   &lt;p&gt;The Advanced Troubleshooting Workshop for SQL Server 2005, 2008 and R2 provides attendees with SQL Server internals knowledge, practical troubleshooting skills and a proven methodical approach to problem solving. The workshop will enable attendees to tackle complex SQL Server problems with confidence.&lt;/p&gt; &lt;/blockquote&gt;  &lt;blockquote&gt;   &lt;p&gt;Full details and registration &lt;a href="http://www.regonline.co.uk/Register/Checkin.aspx?EventID=1016921&amp;amp;trackingcode=ADT" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt; &lt;/blockquote&gt;  &lt;ul&gt;   &lt;li&gt;&lt;b&gt;Real World Cube Design and Performance Tuning with Analysis Services – Chris Webb – February 2012&lt;/b&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;blockquote&gt;   &lt;p&gt;A two day course that takes real world experience in showing you how to build a best practice Analysis Services cube, covering design issues such as data warehouse design and complex cube modelling. Day two then covers performance optimisation for Analysis Services, including MDX optimisation and cube processing.&lt;/p&gt;    &lt;p&gt;Full details and registration &lt;a href="http://www.regonline.co.uk/Register/Checkin.aspx?EventID=1028948&amp;amp;trackingcode=ADT" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt; &lt;/blockquote&gt;  &lt;ul&gt;   &lt;li&gt;&lt;b&gt;Introduction to Master Data Services with Jeremy Kashel – February 2012&lt;/b&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;blockquote&gt;   &lt;p&gt;An end to end look inside Master Data Services, this full day course will begin with a synopsis of Master Data Management before moving on to an overview of Microsoft SQL Server 2008 R2 Master Data Services (MDS). The remainder of the course will cover the major MDS topics, such as modelling and business rules, which will include a number of practical exercises.&lt;/p&gt;    &lt;p&gt;More details and registration for &lt;a href="http://www.regonline.co.uk/Register/Checkin.aspx?EventID=1028960&amp;amp;trackingcode=ADT" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt; &lt;/blockquote&gt;  &lt;ul&gt;   &lt;li&gt;&lt;b&gt;Introduction to MDX with Chris Webb – March 2012&lt;/b&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;blockquote&gt;   &lt;p&gt;The Introduction to MDX course aims to take you from the point of being a complete beginner with no previous knowledge of MDX up to the point where you can write 90% of the MDX calculations and queries you’ll ever need to write. The three day course covers the basics, such as sets, tuples, members to more advanced concepts such as scoped assignments and performance tuning.&lt;/p&gt;    &lt;p&gt;Full details and registration &lt;a href="http://www.regonline.co.uk/Register/Checkin.aspx?EventID=1026958&amp;amp;trackingcode=ADT" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;/blockquote&gt;&lt;img src="http://blogs.adatis.co.uk/aggbug.aspx?PostID=9986" width="1" height="1"&gt;</description><category domain="http://blogs.adatis.co.uk/blogs/jeremykashel/archive/tags/MDX/default.aspx">MDX</category><category domain="http://blogs.adatis.co.uk/blogs/jeremykashel/archive/tags/Analysis+Services/default.aspx">Analysis Services</category><category domain="http://blogs.adatis.co.uk/blogs/jeremykashel/archive/tags/SQL+Server/default.aspx">SQL Server</category><category domain="http://blogs.adatis.co.uk/blogs/jeremykashel/archive/tags/Events/default.aspx">Events</category><category domain="http://blogs.adatis.co.uk/blogs/jeremykashel/archive/tags/MDM/default.aspx">MDM</category><category domain="http://blogs.adatis.co.uk/blogs/jeremykashel/archive/tags/MDS/default.aspx">MDS</category></item><item><title>HP Business Decision Appliance–PowerPivot in a box!</title><link>http://blogs.adatis.co.uk/blogs/calvinferns/archive/2011/10/27/hp-business-decision-appliance-powerpivot-in-a-box.aspx</link><pubDate>Thu, 27 Oct 2011 08:32:31 GMT</pubDate><guid isPermaLink="false">8d7d37f8-4a66-4c95-9fba-293fa87607dc:9972</guid><dc:creator>Calvin Ferns</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;Further to my blog post about SQL server appliances Microsoft and HP also offer the very exciting Business Decision Appliance.&amp;#160; This contains a preconfigured environment with:&lt;/p&gt;  &lt;blockquote&gt;   &lt;ul&gt;     &lt;li&gt;&lt;font size="1"&gt;Microsoft Windows Server 2008 R2 Enterprise Edition &lt;/font&gt;&lt;/li&gt;      &lt;li&gt;&lt;font size="1"&gt;Microsoft SQL Server 2008 R2 Enterprise Edition with PowerPivot integration for SharePoint&lt;/font&gt; &lt;/li&gt;      &lt;li&gt;&lt;font size="1"&gt;Microsoft SharePoint 2010 Enterprise Edition Prerequisites for SharePoint and PowerPivot&lt;/font&gt; &lt;/li&gt;      &lt;li&gt;&lt;font size="1"&gt;Appliance Administration Console&lt;/font&gt; &lt;/li&gt;      &lt;li&gt;&lt;font size="1"&gt;Appliance-specific SharePoint Home Page&lt;/font&gt; &lt;/li&gt;      &lt;li&gt;&lt;font size="1"&gt;Up to 80 &lt;em&gt;Concurrent&lt;/em&gt; Users&lt;/font&gt; &lt;/li&gt;   &lt;/ul&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;font size="1"&gt;The aim of this appliance is to provide a safe and scalable environment for business users to quickly put a PowerPivot environment in place.&amp;#160; This is isolated from existing systems and can be implemented by a business department with very limited IT involvement.&amp;#160; Its isolated nature is important as many organisations don’t run SharePoint 2010 throughout their enterprise.&amp;#160; PowerPivot authors also need Excel 2010 but once reports are built and deployed they can be shared throughout the business through SharePoint using any web browser.&amp;#160; Anyone who has already tried to set up an integrated SharePoint and PowerPivot environment will know that the installation is not simple. This appliance takes that pain away with a one click installation from first start up that can have you up and running in under an hour.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="1"&gt;The key point is that business users love PowerPivot and its ability to quickly use their data to answer any question.&amp;#160; They can respond dynamically, collaborate and share insights throughout the organisation.&amp;#160; Importantly PowerPivot allows the creation of reports that look great and are very fast.&amp;#160; All this is done from within the familiar Excel interface and requiring little training to get started.&amp;#160; Any team of business analysts would likely have a massive boost in productivity from the installation of the BDA in their department.&amp;#160; &lt;/font&gt;&lt;font size="1"&gt;IT can then monitor those reports that are heavily used and decide whether they need making more robust through transition to enterprise software such as Analysis Services.&amp;#160; PowerPivot use is at its easiest in an environment where there is a clean data warehouse but where the business aren&amp;#39;t happy with the speed or responsiveness to change of their current front end.&amp;#160; In an environment with more disparate and dirty data the end users need to be more SQL and data modelling skilled, but the payback can be even greater. &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="1"&gt;I see massive opportunity in this appliance for any team of data analysts to be able to deliver massive value to their business right now.&amp;#160; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="1"&gt;&lt;font size="1"&gt;&lt;a href="http://www.microsoft.com/sqlserver/en/us/solutions-technologies/appliances/hp-ssbi.aspx" target="_blank"&gt;More Info on the BDA&lt;/a&gt;&amp;#160;&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;&lt;img src="http://blogs.adatis.co.uk/aggbug.aspx?PostID=9972" width="1" height="1"&gt;</description><category domain="http://blogs.adatis.co.uk/blogs/calvinferns/archive/tags/Business+Decision+Appliance/default.aspx">Business Decision Appliance</category><category domain="http://blogs.adatis.co.uk/blogs/calvinferns/archive/tags/Appliance/default.aspx">Appliance</category><category domain="http://blogs.adatis.co.uk/blogs/calvinferns/archive/tags/PowerPivot/default.aspx">PowerPivot</category><category domain="http://blogs.adatis.co.uk/blogs/calvinferns/archive/tags/Crescent/default.aspx">Crescent</category><category domain="http://blogs.adatis.co.uk/blogs/calvinferns/archive/tags/SharePoint+2010/default.aspx">SharePoint 2010</category></item><item><title>MDX with Microsoft SQL Server 2008 R2 Analysis Services Cookbook - Book Review</title><link>http://blogs.adatis.co.uk/blogs/jeremykashel/archive/2011/10/13/mdx-with-microsoft-sql-server-2008-r2-analysis-services-cookbook-book-review.aspx</link><pubDate>Thu, 13 Oct 2011 16:51:00 GMT</pubDate><guid isPermaLink="false">8d7d37f8-4a66-4c95-9fba-293fa87607dc:9924</guid><dc:creator>Jeremy Kashel</dc:creator><slash:comments>0</slash:comments><description>&lt;table cellspacing="0" cellpadding="2"&gt;     &lt;tr&gt;       &lt;td&gt;         &lt;p&gt;As you may have already seen, &lt;a href="http://www.packtpub.com/"&gt;Packt&lt;/a&gt; have released a new MDX book, namely &lt;a href="http://www.packtpub.com/mdx-with-microsoft-sql-server-2008-r2-analysis-services/book?utm_source=packtpub.com&amp;amp;utm_medium=article&amp;amp;utm_content=other&amp;amp;utm_campaign=mdb_009103"&gt;MDX with Microsoft SQL Server 2008 R2 Analysis Services Cookbook&lt;/a&gt; by Tomislav Piasevoli.&lt;/p&gt;          &lt;p&gt;The book is written as cookbook, meaning that you can choose the individual ‘recipes’ that apply to whatever problem you’re trying to solve. Each recipe starts off with a section called ‘Getting Ready’, essentially giving you the base query to use, before moving onto ‘How to do it&amp;#39;, which covers the main instructions for the recipe. There are then further sections,&amp;nbsp;which explain how the example works and also suggest other functions/concepts that you may want to consider. This sort of cookbook style makes it really easy to follow, each recipe is displayed very clearly in the book.&lt;/p&gt;          &lt;p&gt;A wide range of MDX problems are covered, from time calculations to context-aware calculations. Not every piece of the MDX functionality is covered, which is to be expected, given the size of the book. It also doesn’t cover the usual introduction to members/sets etc that MDX books tend to cover, but it’s clearly stated that having a working knowledge of MDX is a pre-requisite for the book.&lt;/p&gt;          &lt;p&gt;I found the copy that I’ve been reading in the Adatis office, but I really do like it, so I’ll definitely be ordering my own copy!&lt;/p&gt;       &lt;/td&gt;        &lt;td align="right"&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/jeremykashel/image_60CB45AC.png"&gt;&lt;img style="border:0px currentColor;padding-top:0px;padding-right:0px;padding-left:0px;display:inline;background-image:none;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/jeremykashel/image_thumb_4E827EEA.png" width="188" height="244" /&gt;&lt;/a&gt;&lt;/td&gt;     &lt;/tr&gt;   &lt;/table&gt;&lt;img src="http://blogs.adatis.co.uk/aggbug.aspx?PostID=9924" width="1" height="1"&gt;</description><category domain="http://blogs.adatis.co.uk/blogs/jeremykashel/archive/tags/MDX/default.aspx">MDX</category><category domain="http://blogs.adatis.co.uk/blogs/jeremykashel/archive/tags/Analysis+Services/default.aspx">Analysis Services</category><category domain="http://blogs.adatis.co.uk/blogs/jeremykashel/archive/tags/Books/default.aspx">Books</category></item><item><title>SQL Server can scale</title><link>http://blogs.adatis.co.uk/blogs/calvinferns/archive/2011/09/21/sql-server-can-scale.aspx</link><pubDate>Wed, 21 Sep 2011 17:52:17 GMT</pubDate><guid isPermaLink="false">8d7d37f8-4a66-4c95-9fba-293fa87607dc:9748</guid><dc:creator>Calvin Ferns</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;If you work in large enterprises you often come across the attitude that Microsoft SQL Server can’t scale.&amp;#160; People therefore turn to vendors such as Oracle and Teradata for solutions at very high cost.&amp;#160; This attitude often comes from in-house experience of a growing SQL database which hits something between 5 and 10TB and starts slowing down and becoming difficult to work with.&amp;#160; These databases are often run on multi-instance servers with shared SAN access and little thought to data fragmentation.&amp;#160; Its no wonder that their environment has problems!&lt;/p&gt;  &lt;h5&gt;&lt;font color="#4f81bd" size="3"&gt;Microsoft Strategy&lt;/font&gt;&lt;/h5&gt;  &lt;p&gt;I was recently invited to a Microsoft partners event which aims to challenge these attitudes and give partners better information to discuss large scale SQL implementations. Their strategy is to use partnership with HP to give SQL server a balanced hardware configuration to run on.&amp;#160; This will solve the major bottleneck which gives SQL Server the performance problems people perceive are with the software.&amp;#160; They have created a range of solutions together to allow SQL server to scale effectively to meet any need.&amp;#160;&amp;#160; The first of these solutions was released a couple of years ago and there are more in the pipeline.&amp;#160; There are real world case studies available from Microsoft detailing the success of this strategy for many early adopters. These solutions are targeted at the workloads they need to run and are detailed below.&lt;/p&gt;  &lt;p&gt;&lt;font color="#4f81bd"&gt;&lt;strong&gt;Warehousing&lt;/strong&gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.microsoft.com/sqlserver/en/us/solutions-technologies/appliances/hp-bdw.aspx" target="_blank"&gt;&amp;lt; 5TB&lt;/a&gt; – HP Business Data Warehouse Appliance&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.microsoft.com/sqlserver/en/us/solutions-technologies/data-warehousing/fast-track.aspx" target="_blank"&gt;20TB – 80TB&lt;/a&gt; – Fast Track Data Warehouse&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.microsoft.com/sqlserver/en/us/solutions-technologies/data-warehousing/HP-pdw.aspx" target="_blank"&gt;126TB – 500TB&lt;/a&gt; – HP Enterprise Data Warehouse Appliance&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;font color="#4f81bd"&gt;Applications/ Consolidation/Private Cloud&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://h71028.www7.hp.com/enterprise/us/en/partners/microsoft-database-consolidation-solution.html" target="_blank"&gt;100VM’s- 10,000VM’s&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;font color="#4f81bd"&gt;OLTP&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.microsoft.com/sqlserver/en/us/solutions-technologies/hp-partnership.aspx" target="_blank"&gt;On the way shortly&lt;/a&gt; - Will scale to the worlds largest OLTP Implementations &lt;/p&gt;  &lt;p&gt;These solutions are all positioned such that they are going to be significantly cheaper than almost any other vendor while providing equal or better performance.&amp;#160; The appliances also provide excellent improvements in time to market, drastically reducing required configuration time.&amp;#160; I would also recommend the 5TB box to anyone building a data warehouse of any size.&amp;#160; This give you the confidence that you are buying a competitively priced server which is optimised for a SQL workload and you are not going to hit any hardware bottlenecks which you might come across on a shared or custom build server.&amp;#160; The evolution of the Microsoft appliance and fast-track structure has also produced predictable benchmarks.&amp;#160; You can choose the performance you need by picking the right server and if you follow the best practices you can be sure that you will achieve the throughput and response time needed.&lt;/p&gt;  &lt;p&gt;Oracle’s Exadata platform claims to be able to manage any workload at any scale.&amp;#160; What they don’t specify in the sales briefs is the amount of configuration required to match the platform to the workload in your environment.&amp;#160; This means you need to invest in a lot of time for your Oracle DBA’s to tune and configure the hardware correctly.&amp;#160; It is then not a comparable product to a SQL server installed on a spare bit of hardware which has very little time invested in it.&amp;#160; &lt;/p&gt;  &lt;p&gt;With a balanced hardware configuration and best practice ETL Microsoft SQL Server can meet any scale requirement asked of it.&amp;#160; So next time you come across the “SQL can’t scale” attitude don’t be afraid to let people know that they are out of date and SQL will be able to meet their requirement at a far lower cost than the competitors.&lt;/p&gt;  &lt;p&gt;(There is another appliance out for self service BI but it deserves a post all of its own - &lt;a href="http://www.microsoft.com/sqlserver/en/us/solutions-technologies/Appliances/HP-ssbi.aspx" target="_blank"&gt;BDA&lt;/a&gt; )&lt;/p&gt;&lt;img src="http://blogs.adatis.co.uk/aggbug.aspx?PostID=9748" width="1" height="1"&gt;</description></item><item><title>Master Data Services Kindle Contest</title><link>http://blogs.adatis.co.uk/blogs/jeremykashel/archive/2011/09/13/master-data-services-kindle-contest.aspx</link><pubDate>Tue, 13 Sep 2011 12:55:09 GMT</pubDate><guid isPermaLink="false">8d7d37f8-4a66-4c95-9fba-293fa87607dc:9716</guid><dc:creator>Jeremy Kashel</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;This is a quick blog post to announce that Adatis are running a contest in conjunction with Packt around Master Data Services. The winner will receive an &lt;strong&gt;Amazon&lt;/strong&gt;&amp;#160;&lt;strong&gt;Kindle&lt;/strong&gt; pre-loaded with our Microsoft SQL Server 2008 R2 Master Data Services book.&lt;/p&gt;  &lt;p&gt;In order to enter, all you need to do is follow @AdatisBI and copy and paste our eBook on Kindle message and retweet it using your twitter account. The message is:&lt;/p&gt;  &lt;p&gt;RT &amp;amp; Follow @AdatisBI for a chance to WIN the #Adatis MDS book pre-loaded on a Kindle ! (&lt;a href="http://bit.ly/roogTd"&gt;http://bit.ly/roogTd&lt;/a&gt;)&lt;/p&gt;  &lt;p&gt;Please mark your retweet with the hashtag (#), so that we can find and consider your entry. Only one entry per person will be accepted.&lt;/p&gt;  &lt;p&gt;You can find out the full details of how to enter, as well as terms and conditions, on the &lt;a href="http://www.adatis.co.uk/bi-solutions/master-data-management/Microsoft-SQL-Server-2008-R2-Master-Data-Services-Book.aspx"&gt;following page&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Good luck!&lt;/p&gt;&lt;img src="http://blogs.adatis.co.uk/aggbug.aspx?PostID=9716" width="1" height="1"&gt;</description><category domain="http://blogs.adatis.co.uk/blogs/jeremykashel/archive/tags/Events/default.aspx">Events</category><category domain="http://blogs.adatis.co.uk/blogs/jeremykashel/archive/tags/MDM/default.aspx">MDM</category><category domain="http://blogs.adatis.co.uk/blogs/jeremykashel/archive/tags/Master+Data+Services/default.aspx">Master Data Services</category><category domain="http://blogs.adatis.co.uk/blogs/jeremykashel/archive/tags/MDS/default.aspx">MDS</category><category domain="http://blogs.adatis.co.uk/blogs/jeremykashel/archive/tags/Master+Data+Management/default.aspx">Master Data Management</category><category domain="http://blogs.adatis.co.uk/blogs/jeremykashel/archive/tags/Books/default.aspx">Books</category></item><item><title>Master Data Services Excel Add-in</title><link>http://blogs.adatis.co.uk/blogs/jeremykashel/archive/2011/08/25/master-data-services-excel-add-in.aspx</link><pubDate>Thu, 25 Aug 2011 08:24:50 GMT</pubDate><guid isPermaLink="false">8d7d37f8-4a66-4c95-9fba-293fa87607dc:9657</guid><dc:creator>Jeremy Kashel</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;Master Data Services in SQL Server Denali now includes an Excel add-in that allows MDS users to add and update data that exists within Master Data Services. For those of you that haven’t had a chance to download the latest CTP, this post gives an overview of what’s possible in the Excel Add-in.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Excel Add-in Overview&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Once you install the Excel add-in (available &lt;a href="http://social.technet.microsoft.com/wiki/contents/articles/3714.aspx"&gt;here&lt;/a&gt; for download) you will see an additional toolbar in the ribbon, as shown below:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/jeremykashel/image_772295A8.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/jeremykashel/image_thumb_0826C38C.png" width="596" height="127" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;At a high level, the following functionality is available within the MDS add-in:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Retrieve members from a master data entity &lt;/li&gt;    &lt;li&gt;Add or Update members (including annotations) and publish the changes back to MDS &lt;/li&gt;    &lt;li&gt;Create entities in MDS if you have sufficient permission &lt;/li&gt;    &lt;li&gt;Run the business rules &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;I don’t want this post to go on for ever, so today I’m going to focus on retrieving and updating members.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Retrieving MDS Entity Members&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;The Excel Add-in comes with a sidebar called the Explorer that can be used to connect to an MDS model and retrieve data from an entity within the model. What I quite like is that there is a filter button that allows a user to specify how to filter the data before loading it. In the example below, I’ve connected to the sample customer model, and have filtered the customer entity to only show customers of type 1 and customers from Seattle:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/jeremykashel/image_742D30F5.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/jeremykashel/image_thumb_5E634898.png" width="533" height="315" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;On the same filtering window its possible to choose the attributes to display. Therefore in the above example, by clicking the ‘Load Data’ button, a filtered list of customer members will be shown:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/jeremykashel/image_11BF0BF5.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/jeremykashel/image_thumb_57CFC908.png" width="467" height="172" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Editing Members&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Once the members have been retrieved, editing is just a simple case of typing into the field that you want to change. In the example below I’ve chosen to change the names of two of the customers, which has caused the cells to be highlighted, informing me of the changes that I’ve made:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/jeremykashel/image_27C57787.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/jeremykashel/image_thumb_27594492.png" width="346" height="102" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Domain-based attributes are also picked up nicely by Excel. Not that I imagine it would make too much sense, but it’s possible to change the Sales District North Western US (WUSSL) to Central US (CEUS), for example. Excel handles this by rendering a drop down for this domain attribute:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/jeremykashel/image_6D6A01A5.png"&gt;&lt;img style="background-image:none;border-right-width:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/jeremykashel/image_thumb_782758FA.png" width="166" height="168" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;As it is in Master Data Manager, within Excel it’s also possible to display a domain attribute’s name.&lt;/p&gt;  &lt;p&gt;Regardless of the type of attribute that gets changed, the changes will just remain in the Excel sheet until I click the publish button:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/jeremykashel/image_0521390C.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/jeremykashel/image_thumb_36ACA6A1.png" width="290" height="83" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Clicking the the publish button will result in being prompted to make an optional annotation for each of the changes:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/jeremykashel/image_0A8FA9B0.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/jeremykashel/image_thumb_433A53BD.png" width="389" height="73" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The annotations, as well as the member updates, will be committed to the Master Data Services database. The end result is that the transactions can be viewed as per 2008 R2 in Master Data Manager, or by right clicking in Excel and choosing ‘View Transactions’.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Summary&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;The Excel add-in doesn’t contain all the functionality available within Master Data Manager, but provides an interface that clearly Excel-based data stewards will be very comfortable with. It’s also much easier to do bulk updates in the Excel front-end, when compared to the web front-end.&lt;/p&gt;  &lt;p&gt;That’s about if for now. There’s more to the Excel add-in, which I’m aiming to cover at &lt;a href="http://www.sqlbits.com/"&gt;SQLBits 9&lt;/a&gt;, plus Master Data Manager has been given a complete overhaul in Denali – hopefully I’ll find the time to cover that soon…&lt;/p&gt;&lt;img src="http://blogs.adatis.co.uk/aggbug.aspx?PostID=9657" width="1" height="1"&gt;</description><category domain="http://blogs.adatis.co.uk/blogs/jeremykashel/archive/tags/Excel/default.aspx">Excel</category><category domain="http://blogs.adatis.co.uk/blogs/jeremykashel/archive/tags/MDM/default.aspx">MDM</category><category domain="http://blogs.adatis.co.uk/blogs/jeremykashel/archive/tags/Master+Data+Services/default.aspx">Master Data Services</category><category domain="http://blogs.adatis.co.uk/blogs/jeremykashel/archive/tags/MDS/default.aspx">MDS</category><category domain="http://blogs.adatis.co.uk/blogs/jeremykashel/archive/tags/Master+Data+Management/default.aspx">Master Data Management</category><category domain="http://blogs.adatis.co.uk/blogs/jeremykashel/archive/tags/Denali/default.aspx">Denali</category></item><item><title>Master Data Services Training</title><link>http://blogs.adatis.co.uk/blogs/jeremykashel/archive/2011/08/22/master-data-services-training.aspx</link><pubDate>Mon, 22 Aug 2011 08:49:26 GMT</pubDate><guid isPermaLink="false">8d7d37f8-4a66-4c95-9fba-293fa87607dc:9637</guid><dc:creator>Jeremy Kashel</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;As I’m sure you’ve seen, registration for &lt;a href="http://www.sqlbits.com/default.aspx"&gt;SQLBits 9 – Query Across the Mersey&lt;/a&gt; is now open.&lt;/p&gt;  &lt;p&gt;This time around I’ll be running a deep-dive training day with &lt;a href="http://blogs.adatis.co.uk/blogs/timkent/default.aspx"&gt;Tim Kent&lt;/a&gt; on Master Data Services. This will be a full day of training, showing you how MDS can be used to manage the master data in your organisation. We’re going to start by giving an overview of Master Data Management, before moving on to covering the following MDS topics in detail:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Installing, configuring, and maintaining Master Data Services &lt;/li&gt;    &lt;li&gt;Creating and using models &lt;/li&gt;    &lt;li&gt;Version management &lt;/li&gt;    &lt;li&gt;Business rules and workflow &lt;/li&gt;    &lt;li&gt;Importing data into Master Data Services &lt;/li&gt;    &lt;li&gt;Integrating with other systems &lt;/li&gt;    &lt;li&gt;Security &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;You can register for the MDS Training day, or one of the &lt;a href="http://www.sqlbits.com/information/TrainingDay.aspx"&gt;other 10 training days&lt;/a&gt;, by using the following &lt;a href="http://www.regonline.com/Register/Checkin.aspx?EventID=987503"&gt;registration page&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Remember, the early bird discount expires at midnight on Friday this week!&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;font color="#ff0000"&gt;Update – &lt;/font&gt;&lt;font color="#000000"&gt;&lt;font color="#ff0000"&gt;We are running another MDS course in February 2012.&lt;/font&gt; &lt;a href="http://blogs.adatis.co.uk/blogs/jeremykashel/archive/2011/11/01/sql-server-training-in-london.aspx"&gt;Click here for the details.&lt;/a&gt;&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;&lt;img src="http://blogs.adatis.co.uk/aggbug.aspx?PostID=9637" width="1" height="1"&gt;</description><category domain="http://blogs.adatis.co.uk/blogs/jeremykashel/archive/tags/MDX/default.aspx">MDX</category><category domain="http://blogs.adatis.co.uk/blogs/jeremykashel/archive/tags/Events/default.aspx">Events</category><category domain="http://blogs.adatis.co.uk/blogs/jeremykashel/archive/tags/Master+Data+Services/default.aspx">Master Data Services</category><category domain="http://blogs.adatis.co.uk/blogs/jeremykashel/archive/tags/MDS/default.aspx">MDS</category><category domain="http://blogs.adatis.co.uk/blogs/jeremykashel/archive/tags/Master+Data+Management/default.aspx">Master Data Management</category></item><item><title>A Pattern To Load Data to Master Data Services via SSIS–Part 2</title><link>http://blogs.adatis.co.uk/blogs/neil/archive/2011/08/18/a-pattern-to-load-data-to-master-data-services-via-ssis-part-2.aspx</link><pubDate>Thu, 18 Aug 2011 16:26:30 GMT</pubDate><guid isPermaLink="false">8d7d37f8-4a66-4c95-9fba-293fa87607dc:9616</guid><dc:creator>Neil Dobner</dc:creator><slash:comments>3</slash:comments><description>&lt;h5&gt;Introduction&lt;/h5&gt;  &lt;p&gt;This is the second part of a series of blog posts intended to show a way to load data in to MDS via SSIS. In &lt;a href="http://blogs.adatis.co.uk/blogs/neil/archive/2011/07/14/a-pattern-to-load-data-to-master-data-services-via-ssis.aspx"&gt;part 1&lt;/a&gt; we have loaded the staging tables with new members and attributes for several entities. In this blog post we are going to extend the SSIS package with tasks to move the data from the staging tables into the MDS Product model and validate these newly inserted members.&lt;/p&gt;  &lt;h5&gt;Completing The Solution&lt;/h5&gt;  &lt;p&gt;We need to move the data from the staging tables into the model. This is carried out by executing the MDS staging sweep process. To achieve this we need to add an Execute SQL Task to the control flow of our package. Rename the task – I’ve called mine ‘SQL – Sweep Stage’ and connect it up to the ‘DFL – Load Staging Tables’ task with a success constraint.&lt;/p&gt;  &lt;p&gt;On the General tab set the connection to MasterDataServices and the SQL Statement as follows:&lt;/p&gt;  &lt;blockquote&gt;   &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;DECLARE &lt;/span&gt;@ModelName   &lt;span style="color:blue;"&gt;NVARCHAR&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;50&lt;span style="color:gray;"&gt;) = &lt;/span&gt;? 
&lt;span style="color:blue;"&gt;DECLARE &lt;/span&gt;@UserName    &lt;span style="color:blue;"&gt;NVARCHAR&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;50&lt;span style="color:gray;"&gt;) = &lt;/span&gt;?
&lt;span style="color:blue;"&gt;DECLARE &lt;/span&gt;@User_ID     &lt;span style="color:blue;"&gt;INT 
DECLARE &lt;/span&gt;@Version_ID  &lt;span style="color:blue;"&gt;INT

SET &lt;/span&gt;@User_ID &lt;span style="color:gray;"&gt;=    (&lt;/span&gt;&lt;span style="color:blue;"&gt;SELECT &lt;/span&gt;ID  
                   &lt;span style="color:blue;"&gt;FROM  &lt;/span&gt;mdm&lt;span style="color:gray;"&gt;.&lt;/span&gt;tblUser u 
                   &lt;span style="color:blue;"&gt;WHERE &lt;/span&gt;u&lt;span style="color:gray;"&gt;.&lt;/span&gt;UserName &lt;span style="color:gray;"&gt;= &lt;/span&gt;@UserName &lt;span style="color:gray;"&gt;) 

&lt;/span&gt;&lt;span style="color:blue;"&gt;SET &lt;/span&gt;@Version_ID &lt;span style="color:gray;"&gt;= (&lt;/span&gt;&lt;span style="color:blue;"&gt;SELECT &lt;/span&gt;&lt;span style="color:magenta;"&gt;MAX&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;ID&lt;span style="color:gray;"&gt;)  
                   &lt;/span&gt;&lt;span style="color:blue;"&gt;FROM &lt;/span&gt;mdm&lt;span style="color:gray;"&gt;.&lt;/span&gt;viw_SYSTEM_SCHEMA_VERSION  
                   &lt;span style="color:blue;"&gt;WHERE &lt;/span&gt;Model_Name &lt;span style="color:gray;"&gt;= &lt;/span&gt;@ModelName&lt;span style="color:gray;"&gt;)
                   

&lt;/span&gt;&lt;span style="color:blue;"&gt;EXECUTE &lt;/span&gt;mdm&lt;span style="color:gray;"&gt;.&lt;/span&gt;udpStagingSweep @User_ID&lt;span style="color:gray;"&gt;, &lt;/span&gt;@Version_ID&lt;span style="color:gray;"&gt;, &lt;/span&gt;1&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;Then add the Parameter mapping as shown below:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/neil/image_7ECDD3A5.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/neil/image_thumb_73A4495B.png" width="463" height="395" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That’s all there is to do to get our data into the model. However this process is asynchronous and before we can validate the model we need to know when the staging sweep has finished. &lt;/p&gt;

&lt;p&gt;Add a For Loop Container task to the control flow of the package and connect it up to the ‘SQL – Sweep Stage’ task with a success constraint. Rename the task – I’ve called mine ‘FLC – Wait Until Batch Completes’. Add an Execute SQL Task inside the loop container task and rename it. Mine is called ‘SQL – Get Staging Batch Status’. Change the connection to MasterDataServices, change the ResultSet property to ‘Single row’ and then add the following SQL script to the SQLStatement property:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;DECLARE &lt;/span&gt;@Version_ID &lt;span style="color:blue;"&gt;INT

SET &lt;/span&gt;@Version_ID &lt;span style="color:gray;"&gt;= (&lt;/span&gt;&lt;span style="color:blue;"&gt;SELECT &lt;/span&gt;&lt;span style="color:magenta;"&gt;MAX&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;ID&lt;span style="color:gray;"&gt;)  
                   &lt;/span&gt;&lt;span style="color:blue;"&gt;FROM &lt;/span&gt;mdm&lt;span style="color:gray;"&gt;.&lt;/span&gt;viw_SYSTEM_SCHEMA_VERSION  
                   &lt;span style="color:blue;"&gt;WHERE &lt;/span&gt;Model_Name &lt;span style="color:gray;"&gt;= &lt;/span&gt;?&lt;span style="color:gray;"&gt;)

&lt;/span&gt;&lt;span style="color:blue;"&gt;SELECT TOP    &lt;/span&gt;1 Status_ID 
&lt;span style="color:blue;"&gt;FROM          &lt;/span&gt;mdm&lt;span style="color:gray;"&gt;.&lt;/span&gt;tblStgBatch 
&lt;span style="color:blue;"&gt;WHERE         &lt;/span&gt;Version_ID &lt;span style="color:gray;"&gt;= &lt;/span&gt;@Version_ID
&lt;span style="color:blue;"&gt;ORDER BY      &lt;/span&gt;ID &lt;span style="color:blue;"&gt;DESC&lt;/span&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;Add the parameter mapping as shown below:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/neil/image_0CA019A1.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/neil/image_thumb_77AE972D.png" width="469" height="398" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And the Result Set as shown below:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/neil/image_53893C9E.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/neil/image_thumb_3E97BA2B.png" width="482" height="410" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Add three more parameters to the package as shown in the table below:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/neil/image_0580DD29.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/neil/image_thumb_336E2FE1.png" width="627" height="103" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next configure the For Loop Properties as shown in the table below:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/neil/image_37787DB3.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/neil/image_thumb_6565D06B.png" width="627" height="61" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The InitExpression value sets the @dtMDSLoopTimer to the current time plus the interval set in our @intMDSTimeout variable. The EvalExpression checks if the @strMDSBatchStatus is either not equal to 2 (Success) or the timeout has expired.&lt;/p&gt;

&lt;p&gt;The For Loop Container can only succeed if the staging batch is successfully loaded.&lt;/p&gt;

&lt;p&gt;Now we can validate the model so add an Execute SQL Task to the control flow and connect it to the ‘FLC – Wait Until Batch Completes’ task with a success constraint. Rename the task - mine is called ‘SQL – Validate Model’. Change the connection to MasterDataServices and the SQLStatement as follows:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;DECLARE &lt;/span&gt;@ModelName    &lt;span style="color:blue;"&gt;NVARCHAR&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;50&lt;span style="color:gray;"&gt;) = &lt;/span&gt;?
&lt;span style="color:blue;"&gt;DECLARE &lt;/span&gt;@UserName     &lt;span style="color:blue;"&gt;NVARCHAR&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;50&lt;span style="color:gray;"&gt;) = &lt;/span&gt;?
&lt;span style="color:blue;"&gt;DECLARE &lt;/span&gt;@User_ID      &lt;span style="color:blue;"&gt;INT 
DECLARE &lt;/span&gt;@Version_ID   &lt;span style="color:blue;"&gt;INT
DECLARE &lt;/span&gt;@Model_id     &lt;span style="color:blue;"&gt;INT 


SET &lt;/span&gt;@User_ID &lt;span style="color:gray;"&gt;=        (&lt;/span&gt;&lt;span style="color:blue;"&gt;SELECT &lt;/span&gt;ID  
                       &lt;span style="color:blue;"&gt;FROM  &lt;/span&gt;mdm&lt;span style="color:gray;"&gt;.&lt;/span&gt;tblUser u 
                       &lt;span style="color:blue;"&gt;WHERE &lt;/span&gt;u&lt;span style="color:gray;"&gt;.&lt;/span&gt;UserName &lt;span style="color:gray;"&gt;= &lt;/span&gt;@UserName &lt;span style="color:gray;"&gt;) 

&lt;/span&gt;&lt;span style="color:blue;"&gt;SET &lt;/span&gt;@Version_ID &lt;span style="color:gray;"&gt;=     (&lt;/span&gt;&lt;span style="color:blue;"&gt;SELECT &lt;/span&gt;&lt;span style="color:magenta;"&gt;MAX&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;ID&lt;span style="color:gray;"&gt;)  
                       &lt;/span&gt;&lt;span style="color:blue;"&gt;FROM &lt;/span&gt;mdm&lt;span style="color:gray;"&gt;.&lt;/span&gt;viw_SYSTEM_SCHEMA_VERSION  
                       &lt;span style="color:blue;"&gt;WHERE &lt;/span&gt;Model_Name &lt;span style="color:gray;"&gt;= &lt;/span&gt;@ModelName&lt;span style="color:gray;"&gt;)
                   
&lt;/span&gt;&lt;span style="color:blue;"&gt;SET &lt;/span&gt;@Model_ID &lt;span style="color:gray;"&gt;=       (&lt;/span&gt;&lt;span style="color:blue;"&gt;SELECT &lt;/span&gt;Model_ID 
                       &lt;span style="color:blue;"&gt;FROM &lt;/span&gt;mdm&lt;span style="color:gray;"&gt;.&lt;/span&gt;viw_SYSTEM_SCHEMA_VERSION 
                       &lt;span style="color:blue;"&gt;WHERE &lt;/span&gt;Model_Name &lt;span style="color:gray;"&gt;= &lt;/span&gt;@ModelName&lt;span style="color:gray;"&gt;) 


&lt;/span&gt;&lt;span style="color:blue;"&gt;EXECUTE &lt;/span&gt;mdm&lt;span style="color:gray;"&gt;.&lt;/span&gt;udpValidateModel @User_ID&lt;span style="color:gray;"&gt;, &lt;/span&gt;@Model_ID&lt;span style="color:gray;"&gt;, &lt;/span&gt;@Version_ID&lt;span style="color:gray;"&gt;, &lt;/span&gt;1&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;Set the parameter mapping as follows:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/neil/image_13532324.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/neil/image_thumb_7E61A0B0.png" width="540" height="457" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Almost done. Just to finish it off lets add a script task to the control flow and connect it to the ‘FLC – Wait Until Batch Completes’ task with a completion constraint. Change the Evaluation Operation of the constraint to ‘Expression and Constraint’ and set the Expression to ‘@strMDSBatchStatus != 2’. Edit the script and add the following line of code under&amp;#160;&amp;#160; // TODO: Add your code here:&lt;/p&gt;

&lt;pre class="code"&gt;Dts.Events.FireError(0, &lt;span style="color:#a31515;"&gt;&amp;quot;SCR - Fire Error&amp;quot;&lt;/span&gt;, &lt;span style="color:#a31515;"&gt;&amp;quot;MDS Timeout Occurred&amp;quot;&lt;/span&gt;, &lt;span style="color:blue;"&gt;string&lt;/span&gt;.Empty, 0);&lt;/pre&gt;

&lt;p&gt;This task will fire an error event if the MDS staging batch does not complete successfully.&lt;/p&gt;

&lt;p&gt;The finished package control flow should look similar to the following image:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/neil/image_175D70F6.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/neil/image_thumb_454AC3AE.png" width="524" height="575" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Execute this package and then check the Product entity in MDS. It should look something like the following:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/neil/image_5E4693F3.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/neil/image_thumb_6C18D9EE.png" width="644" height="482" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Looking at the other entities you will see that we have added members to three entities and validated all these new members. &lt;/p&gt;

&lt;h5&gt;Summary&lt;/h5&gt;

&lt;p&gt;Over the last two blog posts I have shown a way of automating the loading of data to Master Data Services via SSIS. This pattern can be used to cater for most of your loading requirements. &lt;/p&gt;

&lt;p&gt;That’s it, the completed Integration Services project source code and MDS Model can be downloaded from &lt;a href="http://blogs.adatis.co.uk/files"&gt;here&lt;/a&gt; – (You will need to create a login first).&lt;/p&gt;

&lt;p&gt;Your comments are very welcome.&lt;/p&gt;&lt;img src="http://blogs.adatis.co.uk/aggbug.aspx?PostID=9616" width="1" height="1"&gt;</description><category domain="http://blogs.adatis.co.uk/blogs/neil/archive/tags/SSIS/default.aspx">SSIS</category><category domain="http://blogs.adatis.co.uk/blogs/neil/archive/tags/Integration+Services/default.aspx">Integration Services</category><category domain="http://blogs.adatis.co.uk/blogs/neil/archive/tags/MDS/default.aspx">MDS</category><category domain="http://blogs.adatis.co.uk/blogs/neil/archive/tags/Master+Data+Services/default.aspx">Master Data Services</category><category domain="http://blogs.adatis.co.uk/blogs/neil/archive/tags/SQL+Server/default.aspx">SQL Server</category></item><item><title>Slides from Avon Information management talk</title><link>http://blogs.adatis.co.uk/blogs/calvinferns/archive/2011/07/21/slides-from-avon-information-management-talk.aspx</link><pubDate>Thu, 21 Jul 2011 11:42:43 GMT</pubDate><guid isPermaLink="false">8d7d37f8-4a66-4c95-9fba-293fa87607dc:9345</guid><dc:creator>Calvin Ferns</dc:creator><slash:comments>2</slash:comments><description>&lt;p&gt;Distributing the slides from my talk last night, it was well received and I think everyone was able to take something away.&lt;/p&gt;  &lt;p&gt;Credit goes to Marco Russo and Alberto Ferrari for their data modelling ideas, visit &lt;a href="http://www.sqlbi.com"&gt;www.sqlbi.com&lt;/a&gt;&amp;#160; &lt;/p&gt;  &lt;p&gt;&lt;a title="http://dl.dropbox.com/u/25925341/Learning%27s%20from%20large%20scale%20dw%20project.pptx" href="http://dl.dropbox.com/u/25925341/Learning%27s%20from%20large%20scale%20dw%20project.pptx"&gt;http://dl.dropbox.com/u/25925341/Learning%27s%20from%20large%20scale%20dw%20project.pptx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Hopefully not my last talk as i enjoyed doing it.&amp;#160; Look out for further Bath based events at: &lt;/p&gt;  &lt;p&gt;&lt;a title="http://avonim.wordpress.com/" href="http://avonim.wordpress.com/"&gt;http://avonim.wordpress.com/&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;All comments welcome&lt;/p&gt;  &lt;p&gt;Calvin&lt;/p&gt;&lt;img src="http://blogs.adatis.co.uk/aggbug.aspx?PostID=9345" width="1" height="1"&gt;</description></item><item><title>A Pattern To Load Data to Master Data Services via SSIS</title><link>http://blogs.adatis.co.uk/blogs/neil/archive/2011/07/14/a-pattern-to-load-data-to-master-data-services-via-ssis.aspx</link><pubDate>Thu, 14 Jul 2011 15:37:00 GMT</pubDate><guid isPermaLink="false">8d7d37f8-4a66-4c95-9fba-293fa87607dc:9298</guid><dc:creator>Neil Dobner</dc:creator><slash:comments>3</slash:comments><description>&lt;h2&gt;&lt;/h2&gt;  &lt;h5&gt;Part 1&lt;/h5&gt;  &lt;h5&gt;Introduction&lt;/h5&gt;  &lt;p&gt;Loading new members to a MDS entity will be a common requirement in all MDS implementations. In these blog posts I am going to walk you through building an SSIS package that performs the following processes:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Load new members and attributes to several entities via staging tables &lt;/li&gt;    &lt;li&gt;Validate the MDS model that contains the entities &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;In part one we will load the MDS staging tables ready to take our new members and attributes into our MDS model. For a thorough understanding of the staging process in MDS please see the Master Data Services Team blog post on &lt;a href="http://sqlblog.com/blogs/mds_team/archive/2010/02/10/Importing-Data-by-Using-the-Staging-Process.aspx"&gt;Importing Data by Using the Staging Process&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;A pre-requisite is to have the AdventureWorks2008R2 database samples installed on the same instance of SQL Server as Master Data Services.&lt;/p&gt;  &lt;p&gt;In MDS I have created a model named ‘Product’ with an entity of the same name. The product entity has the following attributes which are set to the default type and length unless specified:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Name &lt;/li&gt;    &lt;li&gt;Code &lt;/li&gt;    &lt;li&gt;Model (Domain Attribute) &lt;/li&gt;    &lt;li&gt;Culture (Domain Attribute) &lt;/li&gt;    &lt;li&gt;Description (Text, 500) &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;We are going to load this entity with Product data from the AdventureWorks2008R2 database using a SSIS package. &lt;/p&gt;  &lt;p&gt;In addition to this there are two further entities in the Product model:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Culture &lt;/li&gt;    &lt;li&gt;Model &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;These entities have just the code and name attributes and are set to the default type and length. &lt;/p&gt;  &lt;p&gt;The MDS model and Integration Services project source code can be downloaded from &lt;a href="http://blogs.adatis.co.uk/files"&gt;here&lt;/a&gt; – (You will need to create a login first).&lt;/p&gt;  &lt;h5&gt;Building The Solution&lt;/h5&gt;  &lt;p&gt;OK enough of the intro let’s get on and build the package.&lt;/p&gt;  &lt;p&gt;Start a new Visual Studio Integration Services Project and save the default package to a more suitable name. I’ve called mine ‘LoadMDS.dtsx’.&lt;/p&gt;  &lt;p&gt;Create the following connection managers as shown below remembering to replace the Server and MDS database names. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/neil/image_09161AF0.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/neil/image_thumb_2211EB35.png" width="347" height="354" /&gt;&lt;/a&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/neil/image_68FB0E32.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/neil/image_thumb_16E860EB.png" width="345" height="352" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Rename the connection managers to ‘AdventureWorks’ and ‘MasterDataServices’ respectively.&lt;/p&gt;  &lt;p&gt;Now we need to create some variables so go ahead and create the variables shown in the table below: &lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/neil/image_5F871BC5.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/neil/image_thumb_7882EC0A.png" width="601" height="128" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;We are now ready to put our first task into our package. This task will optionally clear the staging tables of all successfully loaded members, attributes and relationships prior to loading, based on the value of the blnClearStage parameter.&lt;/p&gt;  &lt;p&gt;Add an Execute SQL Task to the control flow of your package and rename it - I’ve called mine ‘SQL – Clear Staging Tables’.&lt;/p&gt;  &lt;p&gt;On the General tab set the connection to MasterDataServices and the SQL Statement as follows:&lt;/p&gt;  &lt;div&gt;   &lt;blockquote&gt;     &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;DECLARE &lt;/span&gt;@ModelName &lt;span style="color:blue;"&gt;NVARCHAR&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;50&lt;span style="color:gray;"&gt;) = &lt;/span&gt;? 
&lt;span style="color:blue;"&gt;DECLARE &lt;/span&gt;@UserName  &lt;span style="color:blue;"&gt;NVARCHAR&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;50&lt;span style="color:gray;"&gt;) = &lt;/span&gt;? 
&lt;span style="color:blue;"&gt;DECLARE &lt;/span&gt;@User_ID   &lt;span style="color:blue;"&gt;INT

SET &lt;/span&gt;@User_ID &lt;span style="color:gray;"&gt;=    (&lt;/span&gt;&lt;span style="color:blue;"&gt;SELECT &lt;/span&gt;ID  
                   &lt;span style="color:blue;"&gt;FROM  &lt;/span&gt;mdm&lt;span style="color:gray;"&gt;.&lt;/span&gt;tblUser u 
                   &lt;span style="color:blue;"&gt;WHERE &lt;/span&gt;u&lt;span style="color:gray;"&gt;.&lt;/span&gt;UserName &lt;span style="color:gray;"&gt;= &lt;/span&gt;@UserName &lt;span style="color:gray;"&gt;) 

&lt;/span&gt;&lt;span style="color:blue;"&gt;IF &lt;/span&gt;? &lt;span style="color:gray;"&gt;= &lt;/span&gt;1 
    &lt;span style="color:blue;"&gt;EXECUTE &lt;/span&gt;mdm&lt;span style="color:gray;"&gt;.&lt;/span&gt;udpStagingClear @User_ID&lt;span style="color:gray;"&gt;, &lt;/span&gt;4&lt;span style="color:gray;"&gt;, &lt;/span&gt;1&lt;span style="color:gray;"&gt;, &lt;/span&gt;@ModelName&lt;span style="color:gray;"&gt;, &lt;/span&gt;&lt;span style="color:blue;"&gt;DEFAULT 
ELSE 
    SELECT &lt;/span&gt;1 &lt;span style="color:blue;"&gt;AS &lt;/span&gt;A&lt;/pre&gt;
  &lt;/blockquote&gt;
On the Parameter Mapping tab add the variables exactly as shown below:&lt;/div&gt;

&lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/neil/image_2FE43130.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/neil/image_thumb_76CD542D.png" width="455" height="387" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Add a Data Flow task to the control flow of the package and connect it to the ‘SQL – Clear Staging Tables’ task with a success constraint. Rename the task to ‘DFL – Load Staging Tables’.&lt;/p&gt;

&lt;p&gt;Add three further variables to our package as follows: &lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/neil/image_0041C13C.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/neil/image_thumb_4B35320B.png" width="710" height="116" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the data flow of our package add an OLEDB data source task, set the connection to AdventureWorks and the Data Access Mode to SQL Command. Add the following SQL to the SQL command text window:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;SELECT 
    &lt;/span&gt;&lt;span style="color:magenta;"&gt;CAST&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;p&lt;span style="color:gray;"&gt;.&lt;/span&gt;ProductID &lt;span style="color:blue;"&gt;AS VARCHAR&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;10&lt;span style="color:gray;"&gt;)) + &lt;/span&gt;pmx&lt;span style="color:gray;"&gt;.&lt;/span&gt;CultureID            &lt;span style="color:blue;"&gt;AS &lt;/span&gt;ProductCode
    &lt;span style="color:gray;"&gt;,&lt;/span&gt;p&lt;span style="color:gray;"&gt;.&lt;/span&gt;Name            
    &lt;span style="color:gray;"&gt;,&lt;/span&gt;p&lt;span style="color:gray;"&gt;.&lt;/span&gt;ProductModelID
    &lt;span style="color:gray;"&gt;,&lt;/span&gt;pm&lt;span style="color:gray;"&gt;.&lt;/span&gt;Name                                                    &lt;span style="color:blue;"&gt;AS &lt;/span&gt;ProductModelName
    &lt;span style="color:gray;"&gt;,&lt;/span&gt;pmx&lt;span style="color:gray;"&gt;.&lt;/span&gt;CultureID
    &lt;span style="color:gray;"&gt;,&lt;/span&gt;c&lt;span style="color:gray;"&gt;.&lt;/span&gt;Name                                                     &lt;span style="color:blue;"&gt;AS &lt;/span&gt;CultureName
    &lt;span style="color:gray;"&gt;,&lt;/span&gt;pd&lt;span style="color:gray;"&gt;.&lt;/span&gt;&lt;span style="color:blue;"&gt;Description
FROM &lt;/span&gt;Production&lt;span style="color:gray;"&gt;.&lt;/span&gt;Product                                         p 
  &lt;span style="color:gray;"&gt;INNER JOIN &lt;/span&gt;Production&lt;span style="color:gray;"&gt;.&lt;/span&gt;ProductModel                            pm 
    &lt;span style="color:blue;"&gt;ON &lt;/span&gt;p&lt;span style="color:gray;"&gt;.&lt;/span&gt;ProductModelID &lt;span style="color:gray;"&gt;= &lt;/span&gt;pm&lt;span style="color:gray;"&gt;.&lt;/span&gt;ProductModelID 
  &lt;span style="color:gray;"&gt;INNER JOIN &lt;/span&gt;Production&lt;span style="color:gray;"&gt;.&lt;/span&gt;ProductModelProductDescriptionCulture   pmx 
    &lt;span style="color:blue;"&gt;ON &lt;/span&gt;pm&lt;span style="color:gray;"&gt;.&lt;/span&gt;ProductModelID &lt;span style="color:gray;"&gt;= &lt;/span&gt;pmx&lt;span style="color:gray;"&gt;.&lt;/span&gt;ProductModelID
  &lt;span style="color:gray;"&gt;INNER JOIN &lt;/span&gt;Production&lt;span style="color:gray;"&gt;.&lt;/span&gt;ProductDescription                      pd 
    &lt;span style="color:blue;"&gt;ON &lt;/span&gt;pmx&lt;span style="color:gray;"&gt;.&lt;/span&gt;ProductDescriptionID &lt;span style="color:gray;"&gt;= &lt;/span&gt;pd&lt;span style="color:gray;"&gt;.&lt;/span&gt;ProductDescriptionID
  &lt;span style="color:gray;"&gt;INNER JOIN &lt;/span&gt;Production&lt;span style="color:gray;"&gt;.&lt;/span&gt;Culture                                 c
    &lt;span style="color:blue;"&gt;ON &lt;/span&gt;pmx&lt;span style="color:gray;"&gt;.&lt;/span&gt;CultureID &lt;span style="color:gray;"&gt;= &lt;/span&gt;c&lt;span style="color:gray;"&gt;.&lt;/span&gt;CultureID&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;Don’t worry if the formatting turns ugly, that’s just what happens. Press the Preview button and you will see that this query will return us the following columns to our data flow:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;ProductCode &lt;/li&gt;

  &lt;li&gt;Name &lt;/li&gt;

  &lt;li&gt;ProductModelID &lt;/li&gt;

  &lt;li&gt;ProductModelName &lt;/li&gt;

  &lt;li&gt;CultureID &lt;/li&gt;

  &lt;li&gt;CultureName &lt;/li&gt;

  &lt;li&gt;Description &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We need two more columns in our data flow and to get them we will use a Derived Column transformation task so drag one on to the data flow from the toolbox and connect it up to the data source. Add the columns as shown in the image below:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/neil/image_0FC92473.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/neil/image_thumb_56B24770.png" width="528" height="436" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next the data flow needs to be duplicated into multiple streams so that the different members and attributes can be loaded to the staging tables. This is achieved by adding a Multicast transformation task to our data flow. This task does not require any configuration. There will be six outputs from the Multicast task and these will be used to load the following:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Product Members &lt;/li&gt;

  &lt;li&gt;Model Members &lt;/li&gt;

  &lt;li&gt;Culture Members &lt;/li&gt;

  &lt;li&gt;Product Model Attributes &lt;/li&gt;

  &lt;li&gt;Product Culture Attributes &lt;/li&gt;

  &lt;li&gt;Product Description Attributes &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each of these outputs needs to be tailored as to whether they will be loading a member or an attribute and also which member or attribute they are loading. Add six Derived Column transformation tasks to the data flow and connect them to the Multicast transformation. At this point our data flow should look similar to the following:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/neil/image_41C0C4FD.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/neil/image_thumb_1D9B6A6E.png" width="729" height="231" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For each of the Derived Column transformations add the additional columns as specified below: &lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/neil/image_7163AF92.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/neil/image_thumb_1F51024B.png" width="734" height="342" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;OK now we have got all the information we need in our data flows to start loading to the staging tables but before we do that there is one more thing to do. As we are loading new members to the Model and Culture entities as well as Product we need to ensure that we have only distinct values for our member codes to prevent staging errors. To achieve this we add and connect Aggregate transformation shapes to the data flows underneath the ‘Add Culture Member Information’ and ‘Add Model Member Information’ shapes. The images below show how to configure these aggregate transformation shapes:&lt;/p&gt;

&lt;p&gt;Group By Culture&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Group By Model&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/neil/image_08A9E7FB.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/neil/image_thumb_4F930AF8.png" width="342" height="310" /&gt;&lt;/a&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/neil/image_7D805DB0.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/neil/image_thumb_167C2DF6.png" width="340" height="308" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We are now ready to load the data to the MDS staging tables. Add six OLE DB destination shapes to the dataflow. Three of the destinations will be to load new entity members and the other three will be to load attributes for these new members. Configure the Connection Manager properties of the destinations as follows:&lt;/p&gt;

&lt;p&gt;Members&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Attributes&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/neil/image_018AAB83.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/neil/image_thumb_5D6550F3.png" width="327" height="284" /&gt;&lt;/a&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/neil/image_4873CE80.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/neil/image_thumb_0F5CF17E.png" width="328" height="283" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Connect the first destination shape to the ‘Add Product Member Information’ shape and configure it as a member destination. Click the Mappings tab and set the Input and Destination column mappings as shown below: &lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/neil/image_663A2548.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/neil/image_thumb_5148A2D5.png" width="340" height="259" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Connect the second destination shape to the ‘Group By Culture’ shape and configure it as a Member destination. The column mappings will be the same as above except for the MemberName and MemberCode columns and these will be set to CultureName and CultureID respectively.&lt;/p&gt;

&lt;p&gt;Connect the third destination shape to the ‘Group By Model’ shape and configure it as a Member destination. The column mappings will be the same as above except for the MemberName and MemberCode columns and these will be set to ProductModelName and ProductModelID respectively.&lt;/p&gt;

&lt;p&gt;Connect the fourth destination shape to the ‘Add Culture Attribute Information’ shape and configure it as an Attribute destination. The column mappings will be as follows: &lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/neil/image_7F35F58D.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/neil/image_thumb_1831C5D3.png" width="347" height="286" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Configure the next two destinations as Attribute destinations and map the columns as the other Attribute destination replacing the AttributeValue mapping with ProductModelID and Description respectively. Now our completed dataflow should look similar to the following:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/neil/image_3D4A4436.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/neil/image_thumb_5646147B.png" width="614" height="285" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you execute the package you will see that we have inserted 1764 Product member rows, 6 Culture member rows and 118 Model member rows into the mdm.tblStgMember table and 1764 attribute rows for each of the Culture, Model and Description attributes into the mdm.tblStgMemberAttribute table in your MDS database. It is worth noting that the data has now been staged only and we will not see it in our MDS entities yet.&lt;/p&gt;

&lt;p&gt;OK that’s as far as we are going to go in part one. In part two we will extend the package to move the data from the staging tables into the MDS model and validate the newly inserted data.&lt;/p&gt;&lt;img src="http://blogs.adatis.co.uk/aggbug.aspx?PostID=9298" width="1" height="1"&gt;</description><category domain="http://blogs.adatis.co.uk/blogs/neil/archive/tags/SSIS/default.aspx">SSIS</category><category domain="http://blogs.adatis.co.uk/blogs/neil/archive/tags/Integration+Services/default.aspx">Integration Services</category><category domain="http://blogs.adatis.co.uk/blogs/neil/archive/tags/MDS/default.aspx">MDS</category><category domain="http://blogs.adatis.co.uk/blogs/neil/archive/tags/Master+Data+Services/default.aspx">Master Data Services</category><category domain="http://blogs.adatis.co.uk/blogs/neil/archive/tags/SQL+Server/default.aspx">SQL Server</category></item><item><title>Data Quality Services</title><link>http://blogs.adatis.co.uk/blogs/jeremykashel/archive/2011/07/13/data-quality-services.aspx</link><pubDate>Wed, 13 Jul 2011 12:40:17 GMT</pubDate><guid isPermaLink="false">8d7d37f8-4a66-4c95-9fba-293fa87607dc:9288</guid><dc:creator>Jeremy Kashel</dc:creator><slash:comments>1</slash:comments><description>&lt;p&gt;As I’m sure you’ve heard, CTP3 of SQL Server Denali was released yesterday, and can be downloaded &lt;a href="https://www.microsoft.com/betaexperience/pd/SQLDCTP3CTA/enus/"&gt;here&lt;/a&gt;. Denali includes &lt;a href="http://msdn.microsoft.com/en-us/library/ff877917(v=sql.110).aspx"&gt;Data Quality Services&lt;/a&gt; (DQS), Microsoft’s new data cleansing and matching component that’s based on the Zoomix acquisition that occurred a couple of years back. Data Quality Services didn’t make it into the first CTP, but is now available, so I though it would be worth a quick blog post.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Installing Data Quality Services&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Data Quality Services is an option in the main install, but when you go to run the Data Quality Client, you’ll get a message stating that DQS is not installed. As far as I can tell, DQS needs to be installed manually, by running the DQSInstaller.exe, which you can find in the SQL Server Binn directory. This will create two SQL Server databases:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/jeremykashel/image_7C6696E8.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/jeremykashel/image_thumb_434FB9E6.png" width="348" height="193" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Data Quality Client&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Once DQS is configured, you’ll be in a position to use the Data Quality Client, which is a windows application, available in 32 or 64 bit. Once you connect, you’ll get the following screen:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/jeremykashel/image_5C4B8A2B.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/jeremykashel/image_thumb_3C307D6E.png" width="527" height="329" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The knowledge base is the key to how DQS works, being utilised to determine the data quality of your source data. You can create your own knowledge base, using your own data, or even cloud-based data. For this example, I’m going to use the built in knowledge base called DQS Data.&lt;/p&gt;  &lt;p&gt;As an example, I’ve created some data that I want to cleanse. It’s adventure works country data that I’ve put into a separate table that I’ve called dbo.Country.&lt;/p&gt;  &lt;p&gt;My task now is is to clean this data, which I can do by creating a data quality project:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/jeremykashel/image_552C4DB3.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/jeremykashel/image_thumb_6E281DF8.png" width="296" height="163" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;I’ve called my project Countries, and I’ve picked the built-in DQS Data knowledge base, which I noticed contains reference data for countries. The activity that I’ve selected is Cleansing, and then I’ve clicked Create.&lt;/p&gt;  &lt;p&gt;DQS will then prompt for mapping the source data to one of the domains in the Knowledge Base. Here I’ve mapping my country name to the Country domain from the knowledge base:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/jeremykashel/image_1C1570B1.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/jeremykashel/image_thumb_4A02C369.png" width="431" height="242" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;After clicking the Start button on the next screen, the cleaning process starts, which gives the following results:&lt;/p&gt;      &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/jeremykashel/image_351140F6.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/jeremykashel/image_thumb_4E0D113B.png" width="642" height="248" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;I put a couple of typos into my source data, such as changing Algeria to ‘Algerian’ and Albania to ‘Albana’. These were picked up by DQS, along with a few others, but a user has the opportunity to approve or reject, via the radio buttons shown above. I chose to approve the first two, and then clicked next. In the final screen, DQS allows you to output the cleaned data to a separate table, as shown below:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/jeremykashel/image_7BFA63F3.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/jeremykashel/image_thumb_29E7B6AC.png" width="464" height="200" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;If you go into the table that DQS has created, you will see that there is a Name_Status column, which holds the cleaning status on a per record basis:&lt;/p&gt;    &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/jeremykashel/image_14F63439.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/jeremykashel/image_thumb_42E386F1.png" width="451" height="155" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;This can be used to update the source data, if required, and therefore address the data quality issues.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Summary&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;This has been a quick introduction to cleaning data with Data Quality Services. There’s plenty more to look at, and I hope to find time to do so at some point - In particular I’m keen to take a look at how DQS works with Master Data Services. I’ve noticed that there’s also a new MS DQS blog (&lt;a title="http://blogs.msdn.com/b/dqs/" href="http://blogs.msdn.com/b/dqs/"&gt;http://blogs.msdn.com/b/dqs/&lt;/a&gt;) – I’m sure that will be a great resource for DQS learning.&lt;/p&gt;&lt;img src="http://blogs.adatis.co.uk/aggbug.aspx?PostID=9288" width="1" height="1"&gt;</description><category domain="http://blogs.adatis.co.uk/blogs/jeremykashel/archive/tags/SQL+Server/default.aspx">SQL Server</category><category domain="http://blogs.adatis.co.uk/blogs/jeremykashel/archive/tags/Denali/default.aspx">Denali</category><category domain="http://blogs.adatis.co.uk/blogs/jeremykashel/archive/tags/DQS/default.aspx">DQS</category><category domain="http://blogs.adatis.co.uk/blogs/jeremykashel/archive/tags/Data+Quality+Services/default.aspx">Data Quality Services</category></item><item><title>PowerPivot–Simple Custom Rollup</title><link>http://blogs.adatis.co.uk/blogs/shaunryan/archive/2011/07/05/power-pivot-simple-custom-rollup.aspx</link><pubDate>Tue, 05 Jul 2011 15:08:12 GMT</pubDate><guid isPermaLink="false">8d7d37f8-4a66-4c95-9fba-293fa87607dc:9238</guid><dc:creator>Shaun Ryan</dc:creator><slash:comments>0</slash:comments><description>&lt;h4&gt;&lt;u&gt;Introduction&lt;/u&gt;&lt;/h4&gt;  &lt;p&gt;I have been having a bit of hands on with PowerPivot just lately and one of the aspects of PowerPivot that I think is extremely powerful is that it provides users with the ability to mash up their own data in Excel with data from a structured SQL Server database. More specifically allowing users to create and control how granular attributes of a dimension might rollup up into a hierarchy is a valuable thing, for example an organisational structure or an accounts hierarchy. Users do need to be quite good with data modelling and DAX to leverage PowerPivot and time will tell on that one. However, with that in mind I’m going to create a user controlled custom rollup on an accounts dimension using only very basic data modelling and DAX concepts.&lt;/p&gt;  &lt;p&gt;Essentially within an accounting solution you might want to avoid storing numbers in the context of positive (+ve) and negative (-ve) since in accounting terms either the business owns it or it doesn’t i.e. it’s either an asset or a liability. Also things come into the business and things go out i.e. they purchase supplies and sell goods and services. None of the accounts themselves are either +ve or –ve since in accounting we deal with either credits or debits. Depending on what aspect of the business you’re evaluating and how you’re presenting the figures an account may be considered as in credit for one context but in debit for another. For example the Closing Balance of Stock is considered a Credit in the P&amp;amp;L but a Debit in the Balance Sheet. &lt;/p&gt;  &lt;p&gt;In BI data modelling terms we deal with this by associating the aggregation operator with the reporting dimension hierarchy rather than the number itself thus when the measure is combined with the hierarchy it is aggregated within the context of the hierarchy. More specifically if you’re familiar with SQL Server Analysis Services (SSAS) we do this using a rollup operator that is stored on the accounts dimension.&lt;/p&gt;  &lt;p&gt;This blog is a simple PowerPivot design pattern to allow business users to create their own custom rollups on an accounts dimension and trial balance fact table from SQL Server.&lt;/p&gt;  &lt;h4&gt;&lt;u&gt;Solution&lt;/u&gt;&lt;/h4&gt;  &lt;p&gt;I always like to present the final solution before going into the specifics of the design since knowing the final output tends to make design details a bit easier to digest. So here’s what we’re aiming for:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/shaunryan/Solution---Pivot-Table_57AD72B0.jpg"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="Solution - Pivot Table" border="0" alt="Solution - Pivot Table" src="http://blogs.adatis.co.uk/blogs/shaunryan/Solution---Pivot-Table_thumb_22A0E380.jpg" width="822" height="705" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;So here we can see I’ve got a P&amp;amp;L hierarchy that rolls up the accounts through Gross Profit and Expenses and calculates the Profit. The accounts and figures have all been take from a SQL Server database however which accounts and how they have been rolled up into Cost of Goods Sold, Sales, Gross Profit, Expenses and Net Profit has all been created and controlled by the Excel user. The P&amp;amp;L roll up is created from the following table in the Excel file that is linked into the PowerPivot model:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/shaunryan/Solution---PL-Rollup_0285D6C3.jpg"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="Solution - P&amp;amp;L Rollup" border="0" alt="Solution - P&amp;amp;L Rollup" src="http://blogs.adatis.co.uk/blogs/shaunryan/Solution---PL-Rollup_thumb_496EF9C0.jpg" width="640" height="392" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;So in this table we can see the accounts mapping to relevant parent P&amp;amp;L members and a rollup operator that indicates how the account should be evaluated. The Rollup operators should look familiar if you’re from a SSAS background like me since the symbols are the same. + is for sum, – is subtract and ~ is to exclude. Notice there are many accounts that are not used here since they are not included in the P&amp;amp;L and as such have no parents defined either. A different rollup application might have the numbers excluded from the rollup but still have them included in the hierarchy.&lt;/p&gt;  &lt;h4&gt;&lt;u&gt;Implementation&lt;/u&gt;&lt;/h4&gt;  &lt;p&gt;The underlying SQL Database contains an Accounts dimension, Date dimension and a fact table containing account Balances. The simple star schema is as follows:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/shaunryan/Implementation---DB_626ACA05.jpg"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="Implementation - DB" border="0" alt="Implementation - DB" src="http://blogs.adatis.co.uk/blogs/shaunryan/Implementation---DB_thumb_3E456F76.jpg" width="609" height="296" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;From the diagram we can see that the Account dimension is simply a list of accounts and there is no hierarchy. FactBalance contains the account trial balances which are all physically positive numbers which can conceptually be either summed or subtracted. I’ve included a very simple Date dimension as usual since it’s always good to see how a solution works with more than 1 dimension in play to test and understand what is going on inside the software without making it too complex.&lt;/p&gt;  &lt;p&gt;The next step is to pull these 3 tables into Excel 2010 using the PowerPivot add-in. I won’t go into how this is done in detail since there’s loads on the web about getting started with PowerPivot and I’m assuming if you’re looking to do custom rollup then you’ve already made a start with the basics. This is a pretty good book to get your hands on since it covers the basics and some more advanced topics you can get your teeth into further down the road: &lt;a title="MS Power Pivot for Excel 2010 (Marco and Alberto)" href="http://www.amazon.co.uk/Microsoft%C2%AE-PowerPivot-Excel%C2%AE-2010-ebook/dp/B004D4YIAW" target="_blank"&gt;MS PowerPivot for Excel 2010 (Marco and Alberto)&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Below is the Accounts dimension and Balance fact table that I’ve pulled into PowerPivot and renamed for usability.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/shaunryan/PP-Tables_57413FBB.jpg"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="PP Tables" border="0" alt="PP Tables" src="http://blogs.adatis.co.uk/blogs/shaunryan/PP-Tables_thumb_1E2A62B9.jpg" width="621" height="480" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The next step is to go to the Balance table tab and relate for Account_Key to the Account_Key in the Account table and Date_Key to the Date_Key in the Date table. If your database had these relationships when you imported the tables then PowerPivot will have created them automatically. &lt;/p&gt;  &lt;p&gt;So, now we have our PowerPivot model we’re going to create a table in Excel to rollup the Accounts dimension. Enter the following data into spread sheet in the workbook.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/shaunryan/Mash-Data_372632FE.jpg"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="Mash Data" border="0" alt="Mash Data" src="http://blogs.adatis.co.uk/blogs/shaunryan/Mash-Data_thumb_691DD388.jpg" width="640" height="392" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;With Cell A1 selected click the Link Table icon on the Excel PowerPivot tab.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/shaunryan/Link-Table_0219A3CE.jpg"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="Link Table" border="0" alt="Link Table" src="http://blogs.adatis.co.uk/blogs/shaunryan/Link-Table_thumb_5DF4493E.jpg" width="693" height="268" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;This will import the data into the PowerPivot model linked directly to the data in the Excel sheet. Rename the new table we’ve just imported to something useful and relate the Account dimension to it using the Account Code and it should look like as follows:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/shaunryan/PP-Link-Table_76F01983.jpg"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="PP Link Table" border="0" alt="PP Link Table" src="http://blogs.adatis.co.uk/blogs/shaunryan/PP-Link-Table_thumb_28E7BA0E.jpg" width="640" height="448" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;So now we have all the data nicely imported into PowerPivot and related together we’ll apply the custom rollup. To do this I’m going to use the way that SSAS actually applies the operators under the covers (I believe but am sure someone will correct me if I’m wrong). Essentially + operator multiples the fact data by +1, – multiplies the fact data by –1 and ~ multiplies the fact by 0 or null to effectively yield null. After the operator has been multiplied which adjusts the sign of the data or nulls it out we leave it to PowerPivot to simply sum the result to give the answer. At this point you’re probably right in thinking I could’ve just used +1, –1 and 0 instead of +, – and ~ however I just wanted it to be consistent with what we’re (or I’m) used to in SSAS.&lt;/p&gt;  &lt;p&gt;In the Budget table we’re going to create a calculated column called PL Operator that uses the PowerPivot relationships we’ve defined to pull the operator down into the Budget table. The simple DAX formula I’ve used can be seen in the next screen capture:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/shaunryan/PL-Operator_41E38A53.jpg"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="PL Operator" border="0" alt="PL Operator" src="http://blogs.adatis.co.uk/blogs/shaunryan/PL-Operator_thumb_1DBE2FC4.jpg" width="781" height="638" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Once we have the operator we can create another calculated column to create the PL Amount column that applies the operator by multiplying PL Operator with the Balance as shown below.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/shaunryan/PL-Amount_36BA0009.jpg"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="PL Amount" border="0" alt="PL Amount" src="http://blogs.adatis.co.uk/blogs/shaunryan/PL-Amount_thumb_169EF34C.jpg" width="666" height="789" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;So we can see the PL Amount column now has the rollup operator applied. The only thing left to do is review what columns you want to make visible in the model and drop a pivot table onto a spread sheet and have a look. We could’ve just used 1 calculated column to achieve what we needed to do, I broke it down into 2 just for presentation purposes. Have a play at modifying the Excel based data rollups and refreshing the data model to see how quick and easy it is to manipulate the rollup.&lt;/p&gt;  &lt;h4&gt;&lt;u&gt;Conclusion&lt;/u&gt;&lt;/h4&gt;  &lt;p&gt;This is a really simple way for users to consume data from a database and apply a very simple custom rollup. I really like the simplicity of it and the fact as a user I can just edit my rollups in my sheet and refresh the data and adjust how the accounts roll up. Also you might have noticed there are trial balance figures for the accounts in my data that would be needed to create a balance sheet and so we could progress this further by having another roll up table to create a Balance Sheet. &lt;/p&gt;  &lt;p&gt;I’m going to have a play around a bit more and see if it’s possible to create more complex rollups and perhaps apply different rollup operators for different columns instead of just at the grain of the account. This is where I suspect things will become somewhat more complicated very quickly! Coming from a SSAS background I find it quite useful to take SSAS modelling concepts and challenge my self and PowerPivot to achieve the same end. PowerPivot modelling is a different way of thinking and whilst it may not do what SSAS does out of the box I’m convinced where there is a will there is a way, or maybe not.&lt;/p&gt;&lt;img src="http://blogs.adatis.co.uk/aggbug.aspx?PostID=9238" width="1" height="1"&gt;</description></item><item><title>SSRS Language parameter using SSAS Translations</title><link>http://blogs.adatis.co.uk/blogs/calvinferns/archive/2011/07/05/ssrs-language-parameter-using-ssas-translations.aspx</link><pubDate>Tue, 05 Jul 2011 09:52:24 GMT</pubDate><guid isPermaLink="false">8d7d37f8-4a66-4c95-9fba-293fa87607dc:9236</guid><dc:creator>Calvin Ferns</dc:creator><slash:comments>0</slash:comments><description>&lt;h5&gt;&lt;/h5&gt;  &lt;h5&gt;&lt;/h5&gt;  &lt;h5&gt;Problem&lt;/h5&gt;  &lt;p&gt;SSAS translations are known to deal with warehousing language requirements well.&amp;#160; We recently had a requirement for a multi-language report suite on top of a user browsed cube. First thought was SSAS translations, these will pick up the users local language settings and allow an elegant solution to the problem.&amp;#160; &lt;/p&gt;  &lt;p&gt;However a requirement was put forward for a language picker in the SSRS report suite to over-ride the users locale if they so desire.&amp;#160; This was not so obvious.&lt;/p&gt;  &lt;h5&gt;&lt;/h5&gt;  &lt;h5&gt;Data source&lt;/h5&gt;  &lt;p&gt;We started with a list of languages to build a picker from, this was built by importing the table available here to a SQL Server and building it as a dataset in our report:&lt;/p&gt;  &lt;p&gt;&lt;a title="http://msdn.microsoft.com/en-us/library/0h88fahh.aspx" href="http://msdn.microsoft.com/en-us/library/0h88fahh.aspx"&gt;http://msdn.microsoft.com/en-us/library/0h88fahh.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;It is important to bring through the decimal value in column 4 and the short string in column 2 as we will see later.&lt;/p&gt;  &lt;h5&gt;&lt;/h5&gt;  &lt;h5&gt;Parameter Build&lt;/h5&gt;  &lt;p&gt;Use the dataset on MSDN to build a language select parameter.&amp;#160; Use the language name in the label field and the decimal locale identifier in the value field.&amp;#160; The setup should look something like this:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/calvinferns/image_712771DB.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/calvinferns/image_thumb_6857698F.png" width="527" height="435" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h5&gt;Default value setup&lt;/h5&gt;  &lt;p&gt;If you just need English as the default use the UK code 2057 as your default value, however a more elegant final solution is a little more complex.&amp;#160; &lt;/p&gt;  &lt;p&gt;Reporting services provides the built in variable User!Language which holds the users language in the short string ‘en-gb’ style format.&amp;#160; So although we can access the users language it needs translating into a localeId before we can pass it to SSAS.&amp;#160; Fortunately for us the same table we used above can be used to translate between short string and locale.&lt;/p&gt;  &lt;p&gt;I achieved this using a further hidden parameter defaulted to the built in User!Language variable, the parameter was set up as detailed below:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/calvinferns/image_6E9E401D.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/calvinferns/image_thumb_4E17006B.png" width="536" height="443" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Using the dataset where LanguageCode = short string in our source table&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/calvinferns/image_1ADAC702.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/calvinferns/image_thumb_7E5DD521.png" width="540" height="446" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;If this parameter is run first (it must be earlier in the report parameters list) it will contain the users language in the form ‘en-gb’ in the value and ‘2057’ in the label field.&amp;#160; It is then simple to set the default of the first dropdown parameter to the value of the hidden parameter’s label using the following syntax. &lt;/p&gt;  &lt;p&gt;=Parameters!UserLanguage.Label&lt;/p&gt;  &lt;p&gt;I am open to suggestions of a way to get the default without a hidden parameter or a large switch statement so if you find something more elegant please let me know!&amp;#160; It is also worth noting that if a user has a language that your source table does not have an entry for you are obviously going to lose the defaulting behaviour.&amp;#160; &lt;/p&gt;  &lt;h5&gt;&lt;/h5&gt;    &lt;h5&gt;Parameter Ordering&lt;/h5&gt;  &lt;p&gt;It is essential to make sure that the parameters are ordered in your parameter list in the sequence they need to be evaluated in.&amp;#160; In this case the hidden user language parameter needs to be first, followed by the visible language drop down parameter.&amp;#160; Only then should other report parameters be added.&lt;/p&gt;  &lt;h5&gt;Passing Parameter value to SSAS&lt;/h5&gt;  &lt;p&gt;In order for SSAS to provide us the data in the language requested we need to pass the locale to analysis services.&amp;#160; We can do this by over-riding the locale in the connection string.&amp;#160; Go to your report data source and double click for properties.&amp;#160; Then we need to edit the connection string expression as circled.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/calvinferns/image_04A4ABB0.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/calvinferns/image_thumb_0A7F4F49.png" width="536" height="399" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Here we need to make sure our connection to SSAS is provided with the locale from the parameter.&amp;#160; We use the following expression to build our connections string.&lt;/p&gt;  &lt;p&gt;&lt;font size="3"&gt;=&amp;quot;Data Source=localhost;Initial Catalog=&amp;quot; &amp;amp; CHR(34) &amp;amp; &amp;quot;Adventure Works DW 2008R2&amp;quot; &amp;amp; CHR(34) &amp;amp; &amp;quot;;Locale Identifier=&amp;quot; &amp;amp; Parameters!Language.Value&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="1"&gt;(CHR(34) is the “ character that we wanted to escape properly.)&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="1"&gt;This builds the string detailed below for the parameter selection Spanish.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;=Data Source=localhost;Initial Catalog=&amp;quot;Adventure Works DW 2008R2&amp;quot;;Locale Identifier=3082&lt;/p&gt;  &lt;p&gt;&lt;font size="1"&gt;This should now preview and allow you to select the language and your data sets will return any translations you have present in the cube.&lt;/font&gt;&lt;/p&gt;  &lt;h5&gt;Notes&lt;/h5&gt;  &lt;p&gt;If you are using a shared data source reference this is not going to work for you as it is only possible to expression a data source held in the report.&amp;#160; In this case perhaps you can use a solution along the lines of the one detailed by Mosha here: &lt;a title="http://sqlblog.com/blogs/mosha/archive/2006/10/07/member-caption-translations-in-mdx.aspx" href="http://sqlblog.com/blogs/mosha/archive/2006/10/07/member-caption-translations-in-mdx.aspx"&gt;http://sqlblog.com/blogs/mosha/archive/2006/10/07/member-caption-translations-in-mdx.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Another warning is to finish your report design first because you cant refresh datasets and metadata once the expression is set&lt;/p&gt;  &lt;p&gt;Tested on 2008R2 only.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Hope this helps everyone and allows you to select your existing translations in a flexible way through SSRS.&amp;#160; Your comments are welcome.&lt;/p&gt;&lt;img src="http://blogs.adatis.co.uk/aggbug.aspx?PostID=9236" width="1" height="1"&gt;</description><category domain="http://blogs.adatis.co.uk/blogs/calvinferns/archive/tags/Translations/default.aspx">Translations</category><category domain="http://blogs.adatis.co.uk/blogs/calvinferns/archive/tags/default/default.aspx">default</category><category domain="http://blogs.adatis.co.uk/blogs/calvinferns/archive/tags/language/default.aspx">language</category><category domain="http://blogs.adatis.co.uk/blogs/calvinferns/archive/tags/SSRS/default.aspx">SSRS</category><category domain="http://blogs.adatis.co.uk/blogs/calvinferns/archive/tags/SSAS/default.aspx">SSAS</category><category domain="http://blogs.adatis.co.uk/blogs/calvinferns/archive/tags/parameter/default.aspx">parameter</category></item><item><title>SQLBits 9–Master Data Services Training Day</title><link>http://blogs.adatis.co.uk/blogs/timkent/archive/2011/07/05/sqlbits-9-master-data-services-training-day.aspx</link><pubDate>Tue, 05 Jul 2011 08:25:34 GMT</pubDate><guid isPermaLink="false">8d7d37f8-4a66-4c95-9fba-293fa87607dc:9235</guid><dc:creator>Tim Kent</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;As I’m sure many of you have heard, &lt;a href="http://www.sqlbits.com/"&gt;SQLBits 9&lt;/a&gt; has been announced and will be at the Adelphi Hotel in Liverpool from 29th September to 1st October this year.&amp;#160; &lt;a href="http://blogs.adatis.co.uk/blogs/jeremykashel/default.aspx" target="_blank"&gt;Jeremy&lt;/a&gt; and I will be presenting a full day training on &lt;a href="http://www.sqlbits.com/information/Event9/Master_your_data_with_MDS/TrainingDetails.aspx"&gt;Master Data Services&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;font size="3"&gt;Master your data with MDS&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;A end to end look inside Master Data Services, this full day course will begin with a synopsis of Master Data Management before moving on to an overview of Microsoft SQL Server 2008 R2 Master Data Services (MDS) and then looking in detail at topics such as:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;installing, configuring, and maintaining Master Data Services&lt;/li&gt;    &lt;li&gt;creating and using models&lt;/li&gt;    &lt;li&gt;version management&lt;/li&gt;    &lt;li&gt;business rules and workflow&lt;/li&gt;    &lt;li&gt;importing data into Master Data Services&lt;/li&gt;    &lt;li&gt;Integrating with other systems&lt;/li&gt;    &lt;li&gt;Security.&amp;#160; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;It will also take a brief look at what’s coming next for MDS in the SQL Server Denali.   &lt;br /&gt;This course is for anyone who wants to manage and maintain their business master data and improve data quality with Microsoft SQL Server Master Data Services.&amp;#160; A basic understanding of Microsoft SQL Server is required.&lt;/p&gt;  &lt;p&gt;If you don’t fancy MDS, there are &lt;a href="http://www.sqlbits.com/information/TrainingDay.aspx" target="_blank"&gt;ten other training days&lt;/a&gt; being offered.&lt;/p&gt;  &lt;p&gt;Registration for the training days and conference should be open in the next few weeks and pricing remains the same as last time – an unbelievable £375 for the full conference if you book before 26th August!&lt;/p&gt;&lt;img src="http://blogs.adatis.co.uk/aggbug.aspx?PostID=9235" width="1" height="1"&gt;</description></item><item><title>Adding a Calculated Field to an Excel Pivot Table With Analysis Services</title><link>http://blogs.adatis.co.uk/blogs/jeremykashel/archive/2011/07/01/adding-a-calculated-field-to-an-excel-pivot-table-with-analysis-services.aspx</link><pubDate>Fri, 01 Jul 2011 13:10:17 GMT</pubDate><guid isPermaLink="false">8d7d37f8-4a66-4c95-9fba-293fa87607dc:9207</guid><dc:creator>Jeremy Kashel</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;One question that I get asked from time to time is how to add a calculated field to an Excel Pivot Table that’s connected to an Analysis Services cube. I’ve been aware of a workaround to do this for a while, but a quick Bing :-) revealed that the common answer given to this question is that it’s not possible.&lt;/p&gt;  &lt;p&gt;It definitely is possible, it’s just not that obvious and is perhaps a little limited. Here’s how it can be done in Excel 2010:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Sample Cube&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;First of all, connect to a cube and produce a pivot table report. I’ve connected to the 2008 R2 version of the Adventure Works DW cube and have produced the following report, using the Internet Sales Amount measure:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/jeremykashel/image_7EDE2ECD.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/jeremykashel/image_thumb_17D9FF13.png" width="521" height="174" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Adding a Calculated Field&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;If you now open the Field List, you will see that Internet Sales Amount is selected of course. Here’s the trick – you can select the measure twice by dragging it into the Values area, which will give the following:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/jeremykashel/image_30D5CF58.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/jeremykashel/image_thumb_5EC32210.png" width="405" height="288" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Now click the drop down next to Internet Sales Amount2, which will display the following window:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/jeremykashel/image_10BAC29B.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/jeremykashel/image_thumb_3EA81553.png" width="311" height="278" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;You can change the name of the field – I’ve called mine Percent Share. In the Show Values as drop-down, I’ve picked % of Grand Total, so that I can see the share of the sales in each country across all years. So now the report is as follows:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/jeremykashel/image_57A3E598.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/jeremykashel/image_thumb_42B26325.png" width="698" height="169" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Summary&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;A better approach is to put as many calculations in the cube as possible, but as some calculations requested by users are report-specific, this feature of Pivot Tables allows users to produce the reports that they want.&lt;/p&gt;  &lt;p&gt;The calculations that you can carry out are only those in the ‘Show values as’ drop-down. There’s quite a few in there, especially in Excel 2010, as mentioned &lt;a href="http://blogs.office.com/b/microsoft-excel/archive/2009/10/15/a-few-more-pivottable-improvements-in-excel-2010.aspx"&gt;here&lt;/a&gt;. If that’s not enough, then an alternative is to use the &lt;a href="http://olappivottableextend.codeplex.com/"&gt;OLAP Pivot Table Extensions&lt;/a&gt;, which is available to download on Codeplex.&lt;/p&gt;&lt;img src="http://blogs.adatis.co.uk/aggbug.aspx?PostID=9207" width="1" height="1"&gt;</description><category domain="http://blogs.adatis.co.uk/blogs/jeremykashel/archive/tags/Analysis+Services/default.aspx">Analysis Services</category><category domain="http://blogs.adatis.co.uk/blogs/jeremykashel/archive/tags/Excel/default.aspx">Excel</category></item><item><title>June 2011 Cumulative Update for Master Data Services</title><link>http://blogs.adatis.co.uk/blogs/timkent/archive/2011/06/28/june-2011-cumulative-update-for-master-data-services.aspx</link><pubDate>Tue, 28 Jun 2011 09:52:18 GMT</pubDate><guid isPermaLink="false">8d7d37f8-4a66-4c95-9fba-293fa87607dc:9179</guid><dc:creator>Tim Kent</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;The June CU for SQL Server 2008 R2 includes a good number of fixes and improvements for MDS – Full details and download link:&lt;/p&gt;  &lt;p&gt;&lt;a title="http://support.microsoft.com/kb/2143880" href="http://support.microsoft.com/kb/2143880"&gt;http://support.microsoft.com/kb/2143880&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;After installing you need to go in to the MDS configuration manager and upgrade your MDS database:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/timkent/image_4DBC2CBF.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/timkent/image_thumb_71092164.png" width="924" height="706" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.adatis.co.uk/aggbug.aspx?PostID=9179" width="1" height="1"&gt;</description></item><item><title>Calculating Percentile Brackets using SQL Server 2008</title><link>http://blogs.adatis.co.uk/blogs/david/archive/2011/06/24/calculating-percentile-brackets-using-sql-server-2008.aspx</link><pubDate>Fri, 24 Jun 2011 13:09:41 GMT</pubDate><guid isPermaLink="false">8d7d37f8-4a66-4c95-9fba-293fa87607dc:9145</guid><dc:creator>David Morrison</dc:creator><slash:comments>3</slash:comments><description>&lt;p&gt;Ever had to do statistical analysis on data in sql server? Maybe for reporting or to generate some data for things such as KPI’s in SSAS for example. One aspect of doing data analysis I found interesting and challenging in equal measure is percentiles. What is a percentile I hear you ask? (if you know what a percentile is just skip past this bit)&amp;#160; &lt;/p&gt;  &lt;p&gt;Well imagine you and 99 other people take a test and that the test is scored numerically. Now generally people being people would like to know how many of their follow exam takers they’ve beaten in the exam (I know I would &lt;img style="border-bottom-style:none;border-right-style:none;border-top-style:none;border-left-style:none;" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://blogs.adatis.co.uk/blogs/david/wlEmoticon-smile_6C9E0699.png" /&gt;). So in our example if you’ve done pretty well and say scored better than 80 of your fellow 99 exam takers, then you would be better than 80% of them and hence you would be in the 80th percentile. This of course is a very simplistic example but you get the idea. &lt;/p&gt;  &lt;p&gt;Personally I feel this is more of a common thing in every day life in the America for example than it is here in the UK but it does crop up a lot in reporting and KPI’s for example. &lt;/p&gt;  &lt;h5&gt;&lt;/h5&gt;  &lt;h5&gt;&lt;/h5&gt;  &lt;h5&gt;&lt;/h5&gt;  &lt;h5&gt;&lt;/h5&gt;  &lt;h5&gt;Which way!?&lt;/h5&gt;  &lt;p&gt;Now in my mind there are two quite distinct “directions” you can take in calculating percentiles. The first is the same as in the example above, you take a score, compare it to the rest of its set or “pot” and work out it’s individual position. The second is where you have a set of percentile “milestones” you wish to calculate (5th, 25th, 50th, 75th and 95th for example), then for each set or “pot” of data you have, you find the value within that pot that is the closest to each of your milestones. &lt;/p&gt;  &lt;p&gt;NB: If you try and do something like this in excel, its worth noting that the PERCENTILE function in excel will actually fabricate a figure that is mathematically exact to the percentile you ask for based on the pot of data its given. Although technically the this is more numerically accurate, in my opinion in 99.9% of cases this is overkill, simply because if you calculate percentile milestones from a pot of data, you &lt;u&gt;should&lt;/u&gt; only ever compare values from that pot to those milestones, making the additional effort to calculate the precise value rather than finding the closest actual value pointless. My preferred method is to select an actual value from the set that is closest to each of the required milestones. &lt;/p&gt;  &lt;p&gt;Each “direction” has its own merits and down points, but I think the decision all boils down to volume, purpose and required accuracy. So using my exam example from earlier, imagine if 100 million people took that test, now think of the follow set of possible scenarios&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;You want to generate and send each person an individualised result sheet, unless you had to in order to give each person their exact percentile, would you really want to run that calculation 100 million times? Probably not, what’s more likely is that you’d take the milestone approach, even if you set 100 milestones (1 per percentile), it would be cheaper to calculate these first and then compare each value to the mile stones to get roughly their percentile&lt;/li&gt;    &lt;li&gt;You allow the test takers to login to a website and see a personalised score sheet and lets say you know that around only 10% of the test takers will login and do this. In this case it would &lt;u&gt;probably&lt;/u&gt; be best to generate each individual score as its requested from the website.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Ultimately the choice is up to you but I’d say the milestone approach generally covers more bases, so that will be the focus for this post from here on in.&lt;/p&gt;  &lt;h5&gt;A worked example&lt;/h5&gt;  &lt;p&gt;So before we dive into the sql I wanted to run though how this works logically. I feel this will make the sql easier to follow as you can concentrate on how the code is working rather than its doing, if that makes sense.&lt;/p&gt;  &lt;p&gt;So lets take our demo data pot below&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/david/image_2C67ED1F.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/david/image_thumb_2BFBBA2A.png" width="187" height="515" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;This is a fictitious set of sales figures by store and sales person, each person value is unique within a store and each unique person has one row each (imagine this is a monthly totals of sales for example).&lt;/p&gt;  &lt;p&gt;So the first thing that needs to happen is the data needs to be sorted, smallest to largest. As you can see I have already done this. The next step is to give each row a position or row number, based on its now sorted location in the pot (see below)&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/david/image_1CE4DB50.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/david/image_thumb_2A4AEE56.png" width="254" height="495" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Then for each row we need to work out it’s percentile in relation to the pot, we do this simply by dividing 100 by the number of rows in the pot (29 in our case), then multiplying the the resulting figure by that rows, row number. So the calc would look something like this: (100/Recs In Pot) * Row Number&lt;/p&gt;  &lt;p&gt;This then gives us each records percentile value relative to its pot (see below):&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/david/image_29065577.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/david/image_thumb_0C896397.png" width="335" height="516" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Now we’ve got the percentile figure for every row what we need to do is evaluate each rows suitability to represent each one of our milestones. In this example I’ll be using 5th, 25th, 50th, 75th and 95th percentiles as my required milestones.&lt;/p&gt;  &lt;p&gt;So to determine the each rows suitability to represent each milestone, we do a calculation per required milestone, subtracting the rows percentile value from the required milestone getting the “absolute” value back (This is a mathematical term, basically what it does is ensure you always return a positive figure). This then gives us a, for each rows percentile value, a “distance” from each milestone. The calculation for the 5th percentile would look something like this: ABS(Row Percentile – 5)&lt;/p&gt;  &lt;p&gt;See the below for the results for these calculations for our demo data pot:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/david/image_2A87718B.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/david/image_thumb_10B33B5C.png" width="457" height="492" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;What this leaves us with is a list of candidate values for each of our milestones. From here it is simply a matter of getting the row with the minimum distance value for each of our milestones (Hence numerically the closest, in either direction, to the percentile milestone). That rows value (&lt;strong&gt;sale value, &lt;strong&gt;not percentile value&lt;/strong&gt;&lt;/strong&gt;) then becomes the value for that given milestone.&lt;/p&gt;  &lt;p&gt;This leaves us with a very tidy table as below:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/david/image_425E32E4.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/david/image_thumb_6D3696F6.png" width="159" height="121" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Then all you need to do in your report or wherever you need to know which percentile bracket your row falls in to is to simply compare the rows value to the above percentile table. so to see of your row is in the 25th to 50th percentile range you’d do something like: If My Row Value &amp;gt;= Percentile25Value and &amp;lt;= Percentile50Value then ……&lt;/p&gt;  &lt;p&gt;All make sense?? good! &lt;img style="border-bottom-style:none;border-right-style:none;border-top-style:none;border-left-style:none;" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://blogs.adatis.co.uk/blogs/david/wlEmoticon-smile_6C9E0699.png" /&gt;&lt;/p&gt;  &lt;h5&gt;&lt;/h5&gt;  &lt;h5&gt;To the code!&lt;/h5&gt;  &lt;p&gt;So by now hopefully you understand logically how this should work so lets see how to do in sql server!&lt;/p&gt;  &lt;p&gt;Ok first of all we need to establish our data set, in this example I am using the adventure works database and working with the [Sales].[SalesOrderDetail] and [Sales].[SalesOrderHeader] tables. I’m using CTE’s here because that’s my style, there are a few ways you can do this, but this is my preferred way. As with all my posts I always say this may not be the out and out best way or maybe it is, but it works for me and works well.&lt;/p&gt;  &lt;p&gt;The first part of the code looks like this:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color:gray;"&gt;;&lt;/span&gt;&lt;span style="color:blue;"&gt;with &lt;/span&gt;SalesDetail &lt;span style="color:blue;"&gt;as
&lt;/span&gt;&lt;span style="color:gray;"&gt;(
    &lt;/span&gt;&lt;span style="color:blue;"&gt;SELECT  &lt;/span&gt;OrderYear&lt;span style="color:gray;"&gt;, &lt;/span&gt;SalesPersonID&lt;span style="color:gray;"&gt;, &lt;/span&gt;LineTotal&lt;span style="color:gray;"&gt;, (&lt;/span&gt;100.00 &lt;span style="color:gray;"&gt;/ &lt;/span&gt;RecsInPot&lt;span style="color:gray;"&gt;) * &lt;/span&gt;PositionInPot &lt;span style="color:blue;"&gt;as &lt;/span&gt;Percentile 
    &lt;span style="color:blue;"&gt;FROM 
    &lt;/span&gt;&lt;span style="color:gray;"&gt;(
        &lt;/span&gt;&lt;span style="color:blue;"&gt;SELECT &lt;/span&gt;&lt;span style="color:magenta;"&gt;year&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;SOH&lt;span style="color:gray;"&gt;.&lt;/span&gt;OrderDate&lt;span style="color:gray;"&gt;) &lt;/span&gt;&lt;span style="color:blue;"&gt;as &lt;/span&gt;OrderYear&lt;span style="color:gray;"&gt;, &lt;/span&gt;SOH&lt;span style="color:gray;"&gt;.&lt;/span&gt;SalesPersonID&lt;span style="color:gray;"&gt;, &lt;/span&gt;SOD&lt;span style="color:gray;"&gt;.&lt;/span&gt;LineTotal 
            &lt;span style="color:gray;"&gt;,&lt;/span&gt;&lt;span style="color:magenta;"&gt;count&lt;/span&gt;&lt;span style="color:gray;"&gt;(*) &lt;/span&gt;&lt;span style="color:blue;"&gt;over &lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;&lt;span style="color:blue;"&gt;partition by &lt;/span&gt;&lt;span style="color:magenta;"&gt;year&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;OrderDate&lt;span style="color:gray;"&gt;), &lt;/span&gt;SalesPersonID&lt;span style="color:gray;"&gt;) &lt;/span&gt;&lt;span style="color:blue;"&gt;as &lt;/span&gt;RecsInPot
            &lt;span style="color:gray;"&gt;,&lt;/span&gt;&lt;span style="color:magenta;"&gt;row_number&lt;/span&gt;&lt;span style="color:gray;"&gt;() &lt;/span&gt;&lt;span style="color:blue;"&gt;over &lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;&lt;span style="color:blue;"&gt;partition by &lt;/span&gt;&lt;span style="color:magenta;"&gt;year&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;OrderDate&lt;span style="color:gray;"&gt;), &lt;/span&gt;SalesPersonID &lt;span style="color:blue;"&gt;order by &lt;/span&gt;LineTotal&lt;span style="color:gray;"&gt;) &lt;/span&gt;&lt;span style="color:blue;"&gt;as &lt;/span&gt;PositionInPot
        &lt;span style="color:blue;"&gt;FROM &lt;/span&gt;Sales&lt;span style="color:gray;"&gt;.&lt;/span&gt;SalesOrderDetail &lt;span style="color:blue;"&gt;as &lt;/span&gt;SOD
        &lt;span style="color:gray;"&gt;JOIN &lt;/span&gt;Sales&lt;span style="color:gray;"&gt;.&lt;/span&gt;SalesOrderHeader &lt;span style="color:blue;"&gt;as &lt;/span&gt;SOH &lt;span style="color:blue;"&gt;on &lt;/span&gt;SOD&lt;span style="color:gray;"&gt;.&lt;/span&gt;SalesOrderID &lt;span style="color:gray;"&gt;= &lt;/span&gt;SOH&lt;span style="color:gray;"&gt;.&lt;/span&gt;SalesOrderID
        &lt;span style="color:blue;"&gt;where &lt;/span&gt;SOH&lt;span style="color:gray;"&gt;.&lt;/span&gt;SalesPersonID &lt;span style="color:gray;"&gt;is not null
    ) &lt;/span&gt;&lt;span style="color:blue;"&gt;as &lt;/span&gt;T
&lt;span style="color:gray;"&gt;)&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;This example varies slightly from the logically worked example above in that this dataset has many “pots” of data within it. In this instance a pot is defined by the OrderYear (which is the year from the SalesOrderHeader OrderDate column) and the SalesPersonID. When we’re done we will be able to see how each sale in each year ranked against all other sales that year with the inclusion of which sales person made the sale. i.e. sales person 123 made a sale of XYZ in 2009, how did that sale compare to all other sales by all other sales people that year.&lt;/p&gt;

&lt;p&gt;As in the logical example we take the data, count the number or records per pot (RecsInPot) and then rank the rows in each pot from lowest to highest based on the value of the sale (PositionInPot). From these figures we then work out each rows percentile figure (Percentile).&lt;/p&gt;

&lt;p&gt;Then for the next phase we add a second CTE based on the results of the first CTE as below:&lt;/p&gt;

&lt;pre class="code"&gt;Candidates &lt;span style="color:blue;"&gt;as 
&lt;/span&gt;&lt;span style="color:gray;"&gt;(
    &lt;/span&gt;&lt;span style="color:blue;"&gt;SELECT  &lt;/span&gt;OrderYear&lt;span style="color:gray;"&gt;, &lt;/span&gt;SalesPersonID&lt;span style="color:gray;"&gt;, &lt;/span&gt;LineTotal
        &lt;span style="color:gray;"&gt;,&lt;/span&gt;&lt;span style="color:magenta;"&gt;abs&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;Percentile &lt;span style="color:gray;"&gt;- &lt;/span&gt;5&lt;span style="color:gray;"&gt;) &lt;/span&gt;&lt;span style="color:blue;"&gt;as &lt;/span&gt;PT5_Candidate
        &lt;span style="color:gray;"&gt;,&lt;/span&gt;&lt;span style="color:magenta;"&gt;abs&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;Percentile &lt;span style="color:gray;"&gt;- &lt;/span&gt;25&lt;span style="color:gray;"&gt;) &lt;/span&gt;&lt;span style="color:blue;"&gt;as &lt;/span&gt;PT25_Candidate
        &lt;span style="color:gray;"&gt;,&lt;/span&gt;&lt;span style="color:magenta;"&gt;abs&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;Percentile &lt;span style="color:gray;"&gt;- &lt;/span&gt;50&lt;span style="color:gray;"&gt;) &lt;/span&gt;&lt;span style="color:blue;"&gt;as &lt;/span&gt;PT50_Candidate
        &lt;span style="color:gray;"&gt;,&lt;/span&gt;&lt;span style="color:magenta;"&gt;abs&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;Percentile &lt;span style="color:gray;"&gt;- &lt;/span&gt;75&lt;span style="color:gray;"&gt;) &lt;/span&gt;&lt;span style="color:blue;"&gt;as &lt;/span&gt;PT75_Candidate
        &lt;span style="color:gray;"&gt;,&lt;/span&gt;&lt;span style="color:magenta;"&gt;abs&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;Percentile &lt;span style="color:gray;"&gt;- &lt;/span&gt;95&lt;span style="color:gray;"&gt;) &lt;/span&gt;&lt;span style="color:blue;"&gt;as &lt;/span&gt;PT95_Candidate 
    &lt;span style="color:blue;"&gt;FROM &lt;/span&gt;SalesDetail &lt;span style="color:blue;"&gt;as &lt;/span&gt;SD
&lt;span style="color:gray;"&gt;)&lt;/span&gt;&lt;/pre&gt;
As you can see I have named this CTE “Candidates” and if you’ll remember back to the logical example earlier this is doing exactly the same thing, assessing the suitability each LineTotals value to represent each of the required milestones (I’m using 5,25,50,75 and 95 here but obviously these can be any values you like)

&lt;p&gt;Next we expand the code further, adding a third CTE called Targets&lt;/p&gt;

&lt;pre class="code"&gt;Targets &lt;span style="color:blue;"&gt;as
&lt;/span&gt;&lt;span style="color:gray;"&gt;(
    &lt;/span&gt;&lt;span style="color:blue;"&gt;SELECT &lt;/span&gt;OrderYear&lt;span style="color:gray;"&gt;, &lt;/span&gt;SalesPersonID
        &lt;span style="color:gray;"&gt;,&lt;/span&gt;&lt;span style="color:magenta;"&gt;min&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;&lt;span style="color:magenta;"&gt;abs&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;Percentile &lt;span style="color:gray;"&gt;- &lt;/span&gt;5&lt;span style="color:gray;"&gt;)) &lt;/span&gt;&lt;span style="color:blue;"&gt;as &lt;/span&gt;PT5_Target
        &lt;span style="color:gray;"&gt;,&lt;/span&gt;&lt;span style="color:magenta;"&gt;min&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;&lt;span style="color:magenta;"&gt;abs&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;Percentile &lt;span style="color:gray;"&gt;- &lt;/span&gt;25&lt;span style="color:gray;"&gt;)) &lt;/span&gt;&lt;span style="color:blue;"&gt;as &lt;/span&gt;PT25_Target
        &lt;span style="color:gray;"&gt;,&lt;/span&gt;&lt;span style="color:magenta;"&gt;min&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;&lt;span style="color:magenta;"&gt;abs&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;Percentile &lt;span style="color:gray;"&gt;- &lt;/span&gt;50&lt;span style="color:gray;"&gt;)) &lt;/span&gt;&lt;span style="color:blue;"&gt;as &lt;/span&gt;PT50_Target
        &lt;span style="color:gray;"&gt;,&lt;/span&gt;&lt;span style="color:magenta;"&gt;min&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;&lt;span style="color:magenta;"&gt;abs&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;Percentile &lt;span style="color:gray;"&gt;- &lt;/span&gt;75&lt;span style="color:gray;"&gt;)) &lt;/span&gt;&lt;span style="color:blue;"&gt;as &lt;/span&gt;PT75_Target
        &lt;span style="color:gray;"&gt;,&lt;/span&gt;&lt;span style="color:magenta;"&gt;min&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;&lt;span style="color:magenta;"&gt;abs&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;Percentile &lt;span style="color:gray;"&gt;- &lt;/span&gt;95&lt;span style="color:gray;"&gt;)) &lt;/span&gt;&lt;span style="color:blue;"&gt;as &lt;/span&gt;PT95_Target
    &lt;span style="color:blue;"&gt;FROM &lt;/span&gt;SalesDetail &lt;span style="color:blue;"&gt;as &lt;/span&gt;SD
    &lt;span style="color:blue;"&gt;GROUP BY &lt;/span&gt;OrderYear&lt;span style="color:gray;"&gt;, &lt;/span&gt;SalesPersonID
&lt;span style="color:gray;"&gt;)
&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;As it says on the tin the “Targets” CTE then works out, for each milestone, the smallest percentile distance from the available set available. After this is just a matter of matching up the targets with the candidates which will then give us the value for each milestone. To do this we add the follow final bit to the code:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;SELECT  &lt;/span&gt;OrderYear&lt;span style="color:gray;"&gt;, &lt;/span&gt;SalesPersonID
    &lt;span style="color:gray;"&gt;,&lt;/span&gt;[Percentile5]
    &lt;span style="color:gray;"&gt;,&lt;/span&gt;[Percentile25]
    &lt;span style="color:gray;"&gt;,&lt;/span&gt;[Percentile50]
    &lt;span style="color:gray;"&gt;,&lt;/span&gt;[Percentile75]
    &lt;span style="color:gray;"&gt;,&lt;/span&gt;[Percentile95]
&lt;span style="color:blue;"&gt;FROM 
&lt;/span&gt;&lt;span style="color:gray;"&gt;(
    &lt;/span&gt;&lt;span style="color:blue;"&gt;SELECT &lt;/span&gt;C&lt;span style="color:gray;"&gt;.&lt;/span&gt;OrderYear&lt;span style="color:gray;"&gt;, &lt;/span&gt;C&lt;span style="color:gray;"&gt;.&lt;/span&gt;SalesPersonID&lt;span style="color:gray;"&gt;, &lt;/span&gt;C&lt;span style="color:gray;"&gt;.&lt;/span&gt;LineTotal&lt;span style="color:gray;"&gt;,
        (
        &lt;/span&gt;&lt;span style="color:blue;"&gt;case
            when &lt;/span&gt;PT95_Candidate &lt;span style="color:gray;"&gt;= &lt;/span&gt;PT95_Target &lt;span style="color:blue;"&gt;then &lt;/span&gt;&lt;span style="color:red;"&gt;&amp;#39;Percentile95&amp;#39;
            &lt;/span&gt;&lt;span style="color:blue;"&gt;when &lt;/span&gt;PT75_Candidate &lt;span style="color:gray;"&gt;= &lt;/span&gt;PT75_Target &lt;span style="color:blue;"&gt;then &lt;/span&gt;&lt;span style="color:red;"&gt;&amp;#39;Percentile75&amp;#39;
            &lt;/span&gt;&lt;span style="color:blue;"&gt;when &lt;/span&gt;PT50_Candidate &lt;span style="color:gray;"&gt;= &lt;/span&gt;PT50_Target &lt;span style="color:blue;"&gt;then &lt;/span&gt;&lt;span style="color:red;"&gt;&amp;#39;Percentile50&amp;#39;
            &lt;/span&gt;&lt;span style="color:blue;"&gt;when &lt;/span&gt;PT25_Candidate &lt;span style="color:gray;"&gt;= &lt;/span&gt;PT25_Target &lt;span style="color:blue;"&gt;then &lt;/span&gt;&lt;span style="color:red;"&gt;&amp;#39;Percentile25&amp;#39;
            &lt;/span&gt;&lt;span style="color:blue;"&gt;when &lt;/span&gt;PT5_Candidate &lt;span style="color:gray;"&gt;= &lt;/span&gt;PT5_Target &lt;span style="color:blue;"&gt;then &lt;/span&gt;&lt;span style="color:red;"&gt;&amp;#39;Percentile5&amp;#39;
        &lt;/span&gt;&lt;span style="color:blue;"&gt;end
        &lt;/span&gt;&lt;span style="color:gray;"&gt;) &lt;/span&gt;&lt;span style="color:blue;"&gt;as &lt;/span&gt;Percentile 
    &lt;span style="color:blue;"&gt;FROM &lt;/span&gt;Candidates &lt;span style="color:blue;"&gt;as &lt;/span&gt;C
    &lt;span style="color:gray;"&gt;JOIN &lt;/span&gt;Targets &lt;span style="color:blue;"&gt;as &lt;/span&gt;T &lt;span style="color:blue;"&gt;on 
        &lt;/span&gt;T&lt;span style="color:gray;"&gt;.&lt;/span&gt;OrderYear &lt;span style="color:gray;"&gt;= &lt;/span&gt;C&lt;span style="color:gray;"&gt;.&lt;/span&gt;OrderYear
        &lt;span style="color:gray;"&gt;and &lt;/span&gt;T&lt;span style="color:gray;"&gt;.&lt;/span&gt;SalesPersonID &lt;span style="color:gray;"&gt;= &lt;/span&gt;C&lt;span style="color:gray;"&gt;.&lt;/span&gt;SalesPersonID
        &lt;span style="color:gray;"&gt;and 
        (
            &lt;/span&gt;PT5_Candidate &lt;span style="color:gray;"&gt;= &lt;/span&gt;PT5_Target
            &lt;span style="color:gray;"&gt;or
            &lt;/span&gt;PT25_Candidate &lt;span style="color:gray;"&gt;= &lt;/span&gt;PT25_Target
            &lt;span style="color:gray;"&gt;or
            &lt;/span&gt;PT50_Candidate &lt;span style="color:gray;"&gt;= &lt;/span&gt;PT50_Target
            &lt;span style="color:gray;"&gt;or
            &lt;/span&gt;PT75_Candidate &lt;span style="color:gray;"&gt;= &lt;/span&gt;PT75_Target
            &lt;span style="color:gray;"&gt;or
            &lt;/span&gt;PT95_Candidate &lt;span style="color:gray;"&gt;= &lt;/span&gt;PT95_Target
        &lt;span style="color:gray;"&gt;)
) &lt;/span&gt;&lt;span style="color:blue;"&gt;as &lt;/span&gt;T 
&lt;span style="color:gray;"&gt;pivot (&lt;/span&gt;&lt;span style="color:magenta;"&gt;max&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;T&lt;span style="color:gray;"&gt;.&lt;/span&gt;LineTotal&lt;span style="color:gray;"&gt;) &lt;/span&gt;&lt;span style="color:blue;"&gt;for &lt;/span&gt;Percentile &lt;span style="color:gray;"&gt;in (&lt;/span&gt;[Percentile5]&lt;span style="color:gray;"&gt;,&lt;/span&gt;[Percentile25]&lt;span style="color:gray;"&gt;,&lt;/span&gt;[Percentile50]&lt;span style="color:gray;"&gt;,&lt;/span&gt;[Percentile75]&lt;span style="color:gray;"&gt;,&lt;/span&gt;[Percentile95]&lt;span style="color:gray;"&gt;)) &lt;/span&gt;&lt;span style="color:blue;"&gt;as &lt;/span&gt;pvt&lt;/pre&gt;


&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;What we’re doing here is pretty straight forward, we select from the Candidates CTE, joining onto the Targets CTE where they match on order year, sales person and if any of their candidate values match onto one of the targets thus making that rows sales value the value that will represent the matched milestone. We are then pivoting each of the percentile values up to make one row per “pot” which can then be easily joined onto the data later on in reports etc to find a given percentile range for each value. &lt;/p&gt;

&lt;h5&gt;&amp;#160;&lt;/h5&gt;

&lt;h5&gt;Finishing up&lt;/h5&gt;

&lt;p&gt;So the whole of the code looks like this &lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:gray;"&gt;;&lt;/span&gt;&lt;span style="color:blue;"&gt;with &lt;/span&gt;SalesDetail &lt;span style="color:blue;"&gt;as
&lt;/span&gt;&lt;span style="color:gray;"&gt;(
    &lt;/span&gt;&lt;span style="color:blue;"&gt;SELECT  &lt;/span&gt;OrderYear&lt;span style="color:gray;"&gt;, &lt;/span&gt;SalesPersonID&lt;span style="color:gray;"&gt;, &lt;/span&gt;LineTotal&lt;span style="color:gray;"&gt;, (&lt;/span&gt;100.00 &lt;span style="color:gray;"&gt;/ &lt;/span&gt;RecsInPot&lt;span style="color:gray;"&gt;) * &lt;/span&gt;PositionInPot &lt;span style="color:blue;"&gt;as &lt;/span&gt;Percentile 
    &lt;span style="color:blue;"&gt;FROM 
    &lt;/span&gt;&lt;span style="color:gray;"&gt;(
        &lt;/span&gt;&lt;span style="color:blue;"&gt;SELECT &lt;/span&gt;&lt;span style="color:magenta;"&gt;year&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;SOH&lt;span style="color:gray;"&gt;.&lt;/span&gt;OrderDate&lt;span style="color:gray;"&gt;) &lt;/span&gt;&lt;span style="color:blue;"&gt;as &lt;/span&gt;OrderYear&lt;span style="color:gray;"&gt;, &lt;/span&gt;SOH&lt;span style="color:gray;"&gt;.&lt;/span&gt;SalesPersonID&lt;span style="color:gray;"&gt;, &lt;/span&gt;SOD&lt;span style="color:gray;"&gt;.&lt;/span&gt;LineTotal 
            &lt;span style="color:gray;"&gt;,&lt;/span&gt;&lt;span style="color:magenta;"&gt;count&lt;/span&gt;&lt;span style="color:gray;"&gt;(*) &lt;/span&gt;&lt;span style="color:blue;"&gt;over &lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;&lt;span style="color:blue;"&gt;partition by &lt;/span&gt;&lt;span style="color:magenta;"&gt;year&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;OrderDate&lt;span style="color:gray;"&gt;), &lt;/span&gt;SalesPersonID&lt;span style="color:gray;"&gt;) &lt;/span&gt;&lt;span style="color:blue;"&gt;as &lt;/span&gt;RecsInPot
            &lt;span style="color:gray;"&gt;,&lt;/span&gt;&lt;span style="color:magenta;"&gt;row_number&lt;/span&gt;&lt;span style="color:gray;"&gt;() &lt;/span&gt;&lt;span style="color:blue;"&gt;over &lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;&lt;span style="color:blue;"&gt;partition by &lt;/span&gt;&lt;span style="color:magenta;"&gt;year&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;OrderDate&lt;span style="color:gray;"&gt;), &lt;/span&gt;SalesPersonID &lt;span style="color:blue;"&gt;order by &lt;/span&gt;LineTotal&lt;span style="color:gray;"&gt;) &lt;/span&gt;&lt;span style="color:blue;"&gt;as &lt;/span&gt;PositionInPot
        &lt;span style="color:blue;"&gt;FROM &lt;/span&gt;Sales&lt;span style="color:gray;"&gt;.&lt;/span&gt;SalesOrderDetail &lt;span style="color:blue;"&gt;as &lt;/span&gt;SOD
        &lt;span style="color:gray;"&gt;JOIN &lt;/span&gt;Sales&lt;span style="color:gray;"&gt;.&lt;/span&gt;SalesOrderHeader &lt;span style="color:blue;"&gt;as &lt;/span&gt;SOH &lt;span style="color:blue;"&gt;on &lt;/span&gt;SOD&lt;span style="color:gray;"&gt;.&lt;/span&gt;SalesOrderID &lt;span style="color:gray;"&gt;= &lt;/span&gt;SOH&lt;span style="color:gray;"&gt;.&lt;/span&gt;SalesOrderID
        &lt;span style="color:blue;"&gt;where &lt;/span&gt;SOH&lt;span style="color:gray;"&gt;.&lt;/span&gt;SalesPersonID &lt;span style="color:gray;"&gt;is not null
    ) &lt;/span&gt;&lt;span style="color:blue;"&gt;as &lt;/span&gt;T
&lt;span style="color:gray;"&gt;),

&lt;/span&gt;Candidates &lt;span style="color:blue;"&gt;as 
&lt;/span&gt;&lt;span style="color:gray;"&gt;(
    &lt;/span&gt;&lt;span style="color:blue;"&gt;SELECT  &lt;/span&gt;OrderYear&lt;span style="color:gray;"&gt;, &lt;/span&gt;SalesPersonID&lt;span style="color:gray;"&gt;, &lt;/span&gt;LineTotal
        &lt;span style="color:gray;"&gt;,&lt;/span&gt;&lt;span style="color:magenta;"&gt;abs&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;Percentile &lt;span style="color:gray;"&gt;- &lt;/span&gt;5&lt;span style="color:gray;"&gt;) &lt;/span&gt;&lt;span style="color:blue;"&gt;as &lt;/span&gt;PT5_Candidate
        &lt;span style="color:gray;"&gt;,&lt;/span&gt;&lt;span style="color:magenta;"&gt;abs&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;Percentile &lt;span style="color:gray;"&gt;- &lt;/span&gt;25&lt;span style="color:gray;"&gt;) &lt;/span&gt;&lt;span style="color:blue;"&gt;as &lt;/span&gt;PT25_Candidate
        &lt;span style="color:gray;"&gt;,&lt;/span&gt;&lt;span style="color:magenta;"&gt;abs&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;Percentile &lt;span style="color:gray;"&gt;- &lt;/span&gt;50&lt;span style="color:gray;"&gt;) &lt;/span&gt;&lt;span style="color:blue;"&gt;as &lt;/span&gt;PT50_Candidate
        &lt;span style="color:gray;"&gt;,&lt;/span&gt;&lt;span style="color:magenta;"&gt;abs&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;Percentile &lt;span style="color:gray;"&gt;- &lt;/span&gt;75&lt;span style="color:gray;"&gt;) &lt;/span&gt;&lt;span style="color:blue;"&gt;as &lt;/span&gt;PT75_Candidate
        &lt;span style="color:gray;"&gt;,&lt;/span&gt;&lt;span style="color:magenta;"&gt;abs&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;Percentile &lt;span style="color:gray;"&gt;- &lt;/span&gt;95&lt;span style="color:gray;"&gt;) &lt;/span&gt;&lt;span style="color:blue;"&gt;as &lt;/span&gt;PT95_Candidate 
    &lt;span style="color:blue;"&gt;FROM &lt;/span&gt;SalesDetail &lt;span style="color:blue;"&gt;as &lt;/span&gt;SD
&lt;span style="color:gray;"&gt;),

&lt;/span&gt;Targets &lt;span style="color:blue;"&gt;as
&lt;/span&gt;&lt;span style="color:gray;"&gt;(
    &lt;/span&gt;&lt;span style="color:blue;"&gt;SELECT &lt;/span&gt;OrderYear&lt;span style="color:gray;"&gt;, &lt;/span&gt;SalesPersonID
        &lt;span style="color:gray;"&gt;,&lt;/span&gt;&lt;span style="color:magenta;"&gt;min&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;&lt;span style="color:magenta;"&gt;abs&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;Percentile &lt;span style="color:gray;"&gt;- &lt;/span&gt;5&lt;span style="color:gray;"&gt;)) &lt;/span&gt;&lt;span style="color:blue;"&gt;as &lt;/span&gt;PT5_Target
        &lt;span style="color:gray;"&gt;,&lt;/span&gt;&lt;span style="color:magenta;"&gt;min&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;&lt;span style="color:magenta;"&gt;abs&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;Percentile &lt;span style="color:gray;"&gt;- &lt;/span&gt;25&lt;span style="color:gray;"&gt;)) &lt;/span&gt;&lt;span style="color:blue;"&gt;as &lt;/span&gt;PT25_Target
        &lt;span style="color:gray;"&gt;,&lt;/span&gt;&lt;span style="color:magenta;"&gt;min&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;&lt;span style="color:magenta;"&gt;abs&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;Percentile &lt;span style="color:gray;"&gt;- &lt;/span&gt;50&lt;span style="color:gray;"&gt;)) &lt;/span&gt;&lt;span style="color:blue;"&gt;as &lt;/span&gt;PT50_Target
        &lt;span style="color:gray;"&gt;,&lt;/span&gt;&lt;span style="color:magenta;"&gt;min&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;&lt;span style="color:magenta;"&gt;abs&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;Percentile &lt;span style="color:gray;"&gt;- &lt;/span&gt;75&lt;span style="color:gray;"&gt;)) &lt;/span&gt;&lt;span style="color:blue;"&gt;as &lt;/span&gt;PT75_Target
        &lt;span style="color:gray;"&gt;,&lt;/span&gt;&lt;span style="color:magenta;"&gt;min&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;&lt;span style="color:magenta;"&gt;abs&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;Percentile &lt;span style="color:gray;"&gt;- &lt;/span&gt;95&lt;span style="color:gray;"&gt;)) &lt;/span&gt;&lt;span style="color:blue;"&gt;as &lt;/span&gt;PT95_Target
    &lt;span style="color:blue;"&gt;FROM &lt;/span&gt;SalesDetail &lt;span style="color:blue;"&gt;as &lt;/span&gt;SD
    &lt;span style="color:blue;"&gt;GROUP BY &lt;/span&gt;OrderYear&lt;span style="color:gray;"&gt;, &lt;/span&gt;SalesPersonID
&lt;span style="color:gray;"&gt;)


&lt;/span&gt;&lt;span style="color:blue;"&gt;SELECT  &lt;/span&gt;OrderYear&lt;span style="color:gray;"&gt;, &lt;/span&gt;SalesPersonID
    &lt;span style="color:gray;"&gt;,&lt;/span&gt;[Percentile5]
    &lt;span style="color:gray;"&gt;,&lt;/span&gt;[Percentile25]
    &lt;span style="color:gray;"&gt;,&lt;/span&gt;[Percentile50]
    &lt;span style="color:gray;"&gt;,&lt;/span&gt;[Percentile75]
    &lt;span style="color:gray;"&gt;,&lt;/span&gt;[Percentile95]
&lt;span style="color:blue;"&gt;FROM 
&lt;/span&gt;&lt;span style="color:gray;"&gt;(
    &lt;/span&gt;&lt;span style="color:blue;"&gt;SELECT &lt;/span&gt;C&lt;span style="color:gray;"&gt;.&lt;/span&gt;OrderYear&lt;span style="color:gray;"&gt;, &lt;/span&gt;C&lt;span style="color:gray;"&gt;.&lt;/span&gt;SalesPersonID&lt;span style="color:gray;"&gt;, &lt;/span&gt;C&lt;span style="color:gray;"&gt;.&lt;/span&gt;LineTotal&lt;span style="color:gray;"&gt;,
        (
        &lt;/span&gt;&lt;span style="color:blue;"&gt;case
            when &lt;/span&gt;PT95_Candidate &lt;span style="color:gray;"&gt;= &lt;/span&gt;PT95_Target &lt;span style="color:blue;"&gt;then &lt;/span&gt;&lt;span style="color:red;"&gt;&amp;#39;Percentile95&amp;#39;
            &lt;/span&gt;&lt;span style="color:blue;"&gt;when &lt;/span&gt;PT75_Candidate &lt;span style="color:gray;"&gt;= &lt;/span&gt;PT75_Target &lt;span style="color:blue;"&gt;then &lt;/span&gt;&lt;span style="color:red;"&gt;&amp;#39;Percentile75&amp;#39;
            &lt;/span&gt;&lt;span style="color:blue;"&gt;when &lt;/span&gt;PT50_Candidate &lt;span style="color:gray;"&gt;= &lt;/span&gt;PT50_Target &lt;span style="color:blue;"&gt;then &lt;/span&gt;&lt;span style="color:red;"&gt;&amp;#39;Percentile50&amp;#39;
            &lt;/span&gt;&lt;span style="color:blue;"&gt;when &lt;/span&gt;PT25_Candidate &lt;span style="color:gray;"&gt;= &lt;/span&gt;PT25_Target &lt;span style="color:blue;"&gt;then &lt;/span&gt;&lt;span style="color:red;"&gt;&amp;#39;Percentile25&amp;#39;
            &lt;/span&gt;&lt;span style="color:blue;"&gt;when &lt;/span&gt;PT5_Candidate &lt;span style="color:gray;"&gt;= &lt;/span&gt;PT5_Target &lt;span style="color:blue;"&gt;then &lt;/span&gt;&lt;span style="color:red;"&gt;&amp;#39;Percentile5&amp;#39;
        &lt;/span&gt;&lt;span style="color:blue;"&gt;end
        &lt;/span&gt;&lt;span style="color:gray;"&gt;) &lt;/span&gt;&lt;span style="color:blue;"&gt;as &lt;/span&gt;Percentile 
    &lt;span style="color:blue;"&gt;FROM &lt;/span&gt;Candidates &lt;span style="color:blue;"&gt;as &lt;/span&gt;C
    &lt;span style="color:gray;"&gt;JOIN &lt;/span&gt;Targets &lt;span style="color:blue;"&gt;as &lt;/span&gt;T &lt;span style="color:blue;"&gt;on 
        &lt;/span&gt;T&lt;span style="color:gray;"&gt;.&lt;/span&gt;OrderYear &lt;span style="color:gray;"&gt;= &lt;/span&gt;C&lt;span style="color:gray;"&gt;.&lt;/span&gt;OrderYear
        &lt;span style="color:gray;"&gt;and &lt;/span&gt;T&lt;span style="color:gray;"&gt;.&lt;/span&gt;SalesPersonID &lt;span style="color:gray;"&gt;= &lt;/span&gt;C&lt;span style="color:gray;"&gt;.&lt;/span&gt;SalesPersonID
        &lt;span style="color:gray;"&gt;and 
        (
            &lt;/span&gt;PT5_Candidate &lt;span style="color:gray;"&gt;= &lt;/span&gt;PT5_Target
            &lt;span style="color:gray;"&gt;or
            &lt;/span&gt;PT25_Candidate &lt;span style="color:gray;"&gt;= &lt;/span&gt;PT25_Target
            &lt;span style="color:gray;"&gt;or
            &lt;/span&gt;PT50_Candidate &lt;span style="color:gray;"&gt;= &lt;/span&gt;PT50_Target
            &lt;span style="color:gray;"&gt;or
            &lt;/span&gt;PT75_Candidate &lt;span style="color:gray;"&gt;= &lt;/span&gt;PT75_Target
            &lt;span style="color:gray;"&gt;or
            &lt;/span&gt;PT95_Candidate &lt;span style="color:gray;"&gt;= &lt;/span&gt;PT95_Target
        &lt;span style="color:gray;"&gt;)
) &lt;/span&gt;&lt;span style="color:blue;"&gt;as &lt;/span&gt;T 
&lt;span style="color:gray;"&gt;pivot (&lt;/span&gt;&lt;span style="color:magenta;"&gt;max&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;T&lt;span style="color:gray;"&gt;.&lt;/span&gt;LineTotal&lt;span style="color:gray;"&gt;) &lt;/span&gt;&lt;span style="color:blue;"&gt;for &lt;/span&gt;Percentile &lt;span style="color:gray;"&gt;in (&lt;/span&gt;[Percentile5]&lt;span style="color:gray;"&gt;,&lt;/span&gt;[Percentile25]&lt;span style="color:gray;"&gt;,&lt;/span&gt;[Percentile50]&lt;span style="color:gray;"&gt;,&lt;/span&gt;[Percentile75]&lt;span style="color:gray;"&gt;,&lt;/span&gt;[Percentile95]&lt;span style="color:gray;"&gt;)) &lt;/span&gt;&lt;span style="color:blue;"&gt;as &lt;/span&gt;pvt&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;For reference the resulting output looks like the below. I’m only showing the top 10 here but run the code for yourself against adventure works to get the full set&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/david/image_33B386FF.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://blogs.adatis.co.uk/blogs/david/image_thumb_3347540A.png" width="492" height="189" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;



&lt;p&gt;As you can see this is a small, lightweight reference table that can easily be used to find were a value would fall. &lt;/p&gt;

&lt;p&gt;Now that’s about it, apart from a quick note to say if you want to test this yourself I’ve actually added a couple of indexes as below, just to support the query, they aren’t essential but they do make enough of a difference to put them on&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;create nonclustered index &lt;/span&gt;[IX_SalesOrderHeader_SalesPersonID_Inc] &lt;span style="color:blue;"&gt;on &lt;/span&gt;[Sales]&lt;span style="color:gray;"&gt;.&lt;/span&gt;[SalesOrderHeader] 
&lt;span style="color:gray;"&gt;(&lt;/span&gt;[SalesPersonID] &lt;span style="color:blue;"&gt;asc&lt;/span&gt;&lt;span style="color:gray;"&gt;)
&lt;/span&gt;include &lt;span style="color:gray;"&gt;(&lt;/span&gt;SalesOrderID&lt;span style="color:gray;"&gt;, &lt;/span&gt;OrderDate&lt;span style="color:gray;"&gt;)
&lt;/span&gt;&lt;span style="color:blue;"&gt;GO



create nonclustered index &lt;/span&gt;idx_SalesOrderDetail_SalesOrder_inc &lt;span style="color:blue;"&gt;on &lt;/span&gt;Sales&lt;span style="color:gray;"&gt;.&lt;/span&gt;SalesOrderDetail
&lt;span style="color:gray;"&gt;(&lt;/span&gt;SalesOrderID&lt;span style="color:gray;"&gt;)
&lt;/span&gt;include &lt;span style="color:gray;"&gt;(&lt;/span&gt;OrderQty&lt;span style="color:gray;"&gt;, &lt;/span&gt;UnitPrice&lt;span style="color:gray;"&gt;, &lt;/span&gt;UnitPriceDiscount&lt;span style="color:gray;"&gt;)
&lt;/span&gt;&lt;/pre&gt;




&lt;p&gt;And that’s it, thanks for sticking with it, I know its been a long one and I hope you’ve learnt something&lt;/p&gt;&lt;img src="http://blogs.adatis.co.uk/aggbug.aspx?PostID=9145" width="1" height="1"&gt;</description></item><item><title>Business Data Warehouse Appliance</title><link>http://blogs.adatis.co.uk/blogs/sachatomey/archive/2011/06/13/business-data-warehouse-applicance.aspx</link><pubDate>Mon, 13 Jun 2011 15:15:00 GMT</pubDate><guid isPermaLink="false">8d7d37f8-4a66-4c95-9fba-293fa87607dc:9056</guid><dc:creator>sachatomey</dc:creator><slash:comments>0</slash:comments><description>&lt;div class="SCX234034739"&gt;   &lt;div style="text-indent:0px;margin-left:0px;" class="OutlineElement Ltr SCX234034739"&gt;     &lt;p style="text-align:left;background-color:transparent;font-style:normal;text-indent:0px;width:auto;font-family:&amp;#39;Segoe UI&amp;#39;, tahoma, verdana, &amp;#39;Sans-Serif&amp;#39;;height:auto;color:windowtext;font-size:8pt;vertical-align:baseline;font-weight:normal;margin-right:24px;" class="Paragraph SCX234034739"&gt;&lt;span style="font-family:calibri, sans-serif;font-size:11pt;" class="TextRun SCX234034739"&gt;Microsoft and HP announced the release of their latest Data Warehousing focused appliance last week, the Business Data Warehouse Appliance (BDW):         &lt;br /&gt;&lt;/span&gt;&lt;a style="text-decoration:none;" class="Hyperlink SCX234034739" href="http://blogs.technet.com/b/dataplatforminsider/archive/2011/06/06/announcing-the-hp-business-data-warehouse-appliance.aspx"&gt;&lt;span style="font-family:calibri, sans-serif;color:#0000ff;font-size:11pt;text-decoration:underline;" class="TextRun Underlined SCX234034739"&gt;http://blogs.technet.com/b/dataplatforminsider/archive/2011/06/06/announcing-the-hp-business-data-warehouse-appliance.aspx&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:calibri, sans-serif;font-size:11pt;" class="TextRun EmptyTextRun SCX234034739"&gt;&lt;/span&gt;&lt;/p&gt;   &lt;/div&gt;    &lt;div style="text-indent:0px;margin-left:0px;" class="OutlineElement Ltr SCX234034739"&gt;     &lt;p style="text-align:left;background-color:transparent;font-style:normal;text-indent:0px;font-family:&amp;#39;Segoe UI&amp;#39;, tahoma, verdana, &amp;#39;Sans-Serif&amp;#39;;color:windowtext;font-size:8pt;vertical-align:baseline;font-weight:normal;" class="Paragraph SCX234034739"&gt;&lt;span style="font-family:calibri, sans-serif;font-size:11pt;" class="TextRun SCX234034739"&gt;Not to be confused with the BDA (the Business Decision Appliance aka the &amp;quot;PowerPivot Appliance&amp;quot;) this latest appliance is targeted at data warehouse workloads and follows the &lt;/span&gt;&lt;a style="text-decoration:none;" class="Hyperlink SCX234034739" href="http://www.microsoft.com/sqlserver/2008/en/us/fasttrack.aspx"&gt;&lt;span style="font-family:calibri, sans-serif;color:#0000ff;font-size:11pt;text-decoration:underline;" class="TextRun Underlined SCX234034739"&gt;Fast Track Data Warehouse&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:calibri, sans-serif;font-size:11pt;" class="TextRun SCX234034739"&gt; principals.&lt;/span&gt;&lt;/p&gt;   &lt;/div&gt;    &lt;div style="text-indent:0px;margin-left:0px;" class="OutlineElement Ltr SCX234034739"&gt;     &lt;p style="text-align:left;background-color:transparent;font-style:normal;text-indent:0px;font-family:&amp;#39;Segoe UI&amp;#39;, tahoma, verdana, &amp;#39;Sans-Serif&amp;#39;;color:windowtext;font-size:8pt;vertical-align:baseline;font-weight:normal;" class="Paragraph SCX234034739"&gt;&lt;span style="font-family:calibri, sans-serif;font-size:11pt;" class="TextRun SCX234034739"&gt;This is great move, and I think they have the sizing just right;&amp;#160; Approx. 5TB-8TB of compressed user data (depending on your achieved compression ratio) will cater for a decent proportion of the warehouses and data marts in operation today. &lt;/span&gt;&lt;/p&gt;   &lt;/div&gt;    &lt;p style="text-align:left;background-color:transparent;font-style:normal;text-indent:0px;font-family:&amp;#39;Segoe UI&amp;#39;, tahoma, verdana, &amp;#39;Sans-Serif&amp;#39;;color:windowtext;margin-left:0px;font-size:8pt;vertical-align:baseline;font-weight:normal;" class="Paragraph SCX234034739"&gt;&lt;span style="font-family:calibri, sans-serif;font-size:11pt;" class="TextRun SCX234034739"&gt;The announcement appears to focus on the fast deployment (they claim it can be installed and configured in around 10 minutes), and that&amp;#39;s pretty impressive but I&amp;#39;d like to know what other appliance specific value they have added to the overall package.&amp;#160; After all, installation and configuration of the appliance is just the tip of the iceberg.&lt;/span&gt;&lt;/p&gt;   &lt;span style="font-family:calibri, sans-serif;font-size:11pt;" class="TextRun SCX234034739"&gt;     &lt;div style="text-indent:0px;margin-left:0px;" class="OutlineElement Ltr SCX105234584"&gt;&lt;/div&gt;     &lt;span style="font-family:calibri, sans-serif;font-size:11pt;" class="TextRun SCX234034739"&gt;I&amp;#39;ve been lucky enough to be involved in a Fast Track Data Warehouse implementation so I have a couple of ideas (some of which we&amp;#39;ve implemented) that I&amp;#39;d like to see baked in to a Data Warehouse Appliance offering:&lt;/span&gt;&lt;/span&gt;     &lt;div style="text-indent:0px;margin-left:0px;" class="OutlineElement Ltr SCX105234584"&gt;&lt;span style="font-family:calibri, sans-serif;font-size:11pt;" class="TextRun SCX234034739"&gt;&lt;/span&gt;&lt;/div&gt;    &lt;div style="text-indent:0px;margin-left:0px;" class="OutlineElement Ltr SCX234034739"&gt;     &lt;ul&gt;       &lt;li&gt;         &lt;div style="text-indent:0px;margin-left:0px;" class="OutlineElement Ltr SCX105234584"&gt;&lt;span style="font-family:calibri, sans-serif;font-size:11pt;" class="TextRun SCX234034739"&gt;&lt;/span&gt;&lt;span style="font-family:calibri, sans-serif;font-size:11pt;" class="TextRun SCX234034739"&gt;&lt;span style="font-family:calibri, sans-serif;font-size:11pt;" class="TextRun SCX105234584"&gt;&lt;strong&gt;Operational Reporting&lt;/strong&gt; (Some of which are already achievable through the SQL Server Management Data Warehouse)                 &lt;br /&gt;&amp;#160;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;          &lt;ul&gt;           &lt;li&gt;             &lt;div style="text-indent:0px;margin-left:0px;" class="OutlineElement Ltr SCX105234584"&gt;&lt;span style="font-family:calibri, sans-serif;font-size:11pt;" class="TextRun SCX234034739"&gt;&lt;span style="font-family:calibri, sans-serif;font-size:11pt;" class="TextRun SCX105234584"&gt;&lt;/span&gt;&lt;span style="font-family:calibri, sans-serif;font-size:11pt;" class="TextRun SCX105234584"&gt;&lt;strong&gt;Disk and File group usage reports&lt;/strong&gt; - Help with on-going capacity planning by detailing growth and trends over time for the disk as a whole and file groups associated with each database.                     &lt;br /&gt;&amp;#160;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;           &lt;/li&gt;            &lt;li&gt;             &lt;div style="text-indent:0px;margin-left:0px;" class="OutlineElement Ltr SCX105234584"&gt;&lt;span style="font-family:calibri, sans-serif;font-size:11pt;" class="TextRun SCX234034739"&gt;&lt;span style="font-family:calibri, sans-serif;font-size:11pt;" class="TextRun SCX105234584"&gt;&lt;/span&gt;&lt;span style="font-family:calibri, sans-serif;font-size:11pt;" class="TextRun SCX105234584"&gt;&lt;strong&gt;Fragmentation Reports&lt;/strong&gt; - [The methodology surrounding Fast Track has a high emphasis on avoiding and managing fragmentation]&amp;#160; Reports that detail levels of fragmentation at both the physical and logical level would potentially pre-empt any fragmentation related issues.&amp;#160; A kind of combination of &lt;/span&gt;&lt;a style="text-decoration:none;" class="Hyperlink SCX105234584" href="http://windirstat.info/"&gt;&lt;span style="font-family:calibri, sans-serif;color:#0000ff;font-size:11pt;text-decoration:underline;" class="TextRun Underlined SCX105234584"&gt;WinDirStat&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:calibri, sans-serif;font-size:11pt;" class="TextRun SCX105234584"&gt; and &lt;/span&gt;&lt;a style="text-decoration:none;" class="Hyperlink SCX105234584" href="http://internalsviewer.codeplex.com/"&gt;&lt;span style="font-family:calibri, sans-serif;color:#0000ff;font-size:11pt;text-decoration:underline;" class="TextRun Underlined SCX105234584"&gt;Internals Viewer&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:calibri, sans-serif;font-size:11pt;" class="TextRun SCX105234584"&gt; would be a great graphical representation of the fragmentation at both those levels.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;           &lt;/li&gt;         &lt;/ul&gt;       &lt;/li&gt;     &lt;/ul&gt;   &lt;/div&gt;    &lt;ul&gt;     &lt;li&gt;       &lt;div style="text-indent:0px;margin-left:0px;" class="OutlineElement Ltr SCX105234584"&gt;&lt;span style="font-family:calibri, sans-serif;font-size:11pt;" class="TextRun SCX234034739"&gt;&lt;span style="font-family:calibri, sans-serif;font-size:11pt;" class="TextRun SCX105234584"&gt;&lt;strong&gt;Database Administration/Developer Accelerators                &lt;br /&gt;&amp;#160;&lt;/strong&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;        &lt;ul&gt;         &lt;li&gt;           &lt;div style="text-indent:0px;margin-left:0px;" class="OutlineElement Ltr SCX105234584"&gt;&lt;span style="font-family:calibri, sans-serif;font-size:11pt;" class="TextRun SCX234034739"&gt;&lt;span style="font-family:calibri, sans-serif;font-size:11pt;" class="TextRun SCX105234584"&gt;&lt;/span&gt;&lt;span style="font-family:calibri, sans-serif;font-size:11pt;" class="TextRun SCX105234584"&gt;&lt;strong&gt;Database/object Creation functions&lt;/strong&gt; - I want to be able to create a database and or a file group of a specific size and let the appliance do the work of creating the physical files on each of the mount points for me.&amp;#160; PDW (SQL Server Parallel Data Warehouse Edition) already does something like this that&amp;#39;s baked into the product.                   &lt;br /&gt;&amp;#160;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;         &lt;/li&gt;          &lt;li&gt;           &lt;div style="text-indent:0px;margin-left:0px;" class="OutlineElement Ltr SCX105234584"&gt;&lt;span style="font-family:calibri, sans-serif;font-size:11pt;" class="TextRun SCX234034739"&gt;&lt;span style="font-family:calibri, sans-serif;font-size:11pt;" class="TextRun SCX105234584"&gt;&lt;/span&gt;&lt;span style="font-family:calibri, sans-serif;font-size:11pt;" class="TextRun SCX105234584"&gt;&lt;strong&gt;Simplified partition management&lt;/strong&gt; - For example, I&amp;#39;m likely to want to age my data over time and merge smaller partitions into larger partitions (certainly until the maximum number of partitions limit is raised in &amp;#39;Denali&amp;#39;), or I might want to remove all the data from a specific partition in preparation for a reload.&amp;#160; Make it easy and handle all the swapping out, multi merging etc for me.                   &lt;br /&gt;&amp;#160;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;         &lt;/li&gt;          &lt;li&gt;           &lt;div style="text-indent:0px;margin-left:0px;" class="OutlineElement Ltr SCX105234584"&gt;&lt;span style="font-family:calibri, sans-serif;font-size:11pt;" class="TextRun SCX234034739"&gt;&lt;span style="font-family:calibri, sans-serif;font-size:11pt;" class="TextRun SCX105234584"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:calibri, sans-serif;font-size:11pt;" class="TextRun SCX234034739"&gt;&lt;span style="font-family:calibri, sans-serif;font-size:11pt;" class="TextRun SCX105234584"&gt;&lt;strong&gt;Fragmentation Management&lt;/strong&gt; - For example, I might want to select 1 or more tables and have them completely rebuilt to remove any extent fragmentation.                   &lt;br /&gt;&amp;#160;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;         &lt;/li&gt;          &lt;li&gt;           &lt;div style="text-indent:0px;margin-left:0px;" class="OutlineElement Ltr SCX105234584"&gt;&lt;span style="font-family:calibri, sans-serif;font-size:11pt;" class="TextRun SCX234034739"&gt;&lt;span style="font-family:calibri, sans-serif;font-size:11pt;" class="TextRun SCX105234584"&gt;&lt;/span&gt;&lt;span style="font-family:calibri, sans-serif;font-size:11pt;" class="TextRun SCX105234584"&gt;&lt;strong&gt;Resize management&lt;/strong&gt; - My file group is approaching full, I need a bigger one, I want a function to perform that resize in a &amp;#39;Fast Track approved&amp;#39; manner.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;           &lt;span class="ListGhost SCX105234584"&gt;&lt;/span&gt;&lt;/li&gt;       &lt;/ul&gt;        &lt;div style="text-indent:0px;margin-left:0px;" class="OutlineElement Ltr SCX105234584"&gt;         &lt;p style="text-align:left;background-color:transparent;font-style:normal;text-indent:0px;font-family:&amp;#39;Segoe UI&amp;#39;, tahoma, verdana, &amp;#39;Sans-Serif&amp;#39;;color:windowtext;font-size:8pt;vertical-align:baseline;font-weight:normal;" class="Paragraph SCX105234584"&gt;&lt;span style="font-family:calibri, sans-serif;font-size:11pt;" class="TextRun SCX105234584"&gt;There&amp;#39;s a whole host of other &amp;#39;value-adds&amp;#39; e.g. a &amp;#39;Best Practice Analyser&amp;#39; that could be included as part of a Data Warehouse appliance, and it will certainly be interesting to see how the appliance develops following adoption over the next few appliance updates/revisions.&lt;/span&gt;&lt;/p&gt;       &lt;/div&gt;     &lt;/li&gt;   &lt;/ul&gt;    &lt;p style="text-align:left;background-color:transparent;font-style:normal;text-indent:0px;font-family:&amp;#39;Segoe UI&amp;#39;, tahoma, verdana, &amp;#39;Sans-Serif&amp;#39;;color:windowtext;font-size:8pt;vertical-align:baseline;font-weight:normal;" class="Paragraph SCX234034739"&gt;&lt;span style="font-family:calibri, sans-serif;font-size:11pt;" class="TextRun SCX234034739"&gt;&lt;/span&gt;&lt;/p&gt; &lt;/div&gt;&lt;img src="http://blogs.adatis.co.uk/aggbug.aspx?PostID=9056" width="1" height="1"&gt;</description></item></channel></rss>
