<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Boyan Penev on Microsoft BI</title>
	
	<link>http://www.bp-msbi.com</link>
	<description>A practical blog about Microsoft BI tools, techniques and practices written by a developer for other fellow developers.</description>
	<lastBuildDate>Sun, 29 Jan 2012 03:23:06 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/bp-msbi" /><feedburner:info uri="bp-msbi" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><creativeCommons:license>http://creativecommons.org/licenses/by/2.5/</creativeCommons:license><item>
		<title>SSAS Locale Identifier Bug</title>
		<link>http://feedproxy.google.com/~r/bp-msbi/~3/lmJMCnPx4kg/</link>
		<comments>http://www.bp-msbi.com/2012/01/ssas-locale-identifier-bug/#comments</comments>
		<pubDate>Sun, 29 Jan 2012 03:23:06 +0000</pubDate>
		<dc:creator>Boyan Penev</dc:creator>
				<category><![CDATA[SSAS]]></category>
		<category><![CDATA[bug]]></category>

		<guid isPermaLink="false">http://www.bp-msbi.com/?p=472</guid>
		<description><![CDATA[These days I have two little problems with SSAS. One is really small &#8211; I really don&#8217;t like how the Process dialog in BIDS (2008 R2) stays blank during the process operation and how I need to click on &#8220;Stop&#8221; after it finishes. The fact that such a bug had gotten into the product and [...]]]></description>
			<content:encoded><![CDATA[<p>These days I have two little problems with SSAS. One is really small &#8211; I really don&#8217;t like how the Process dialog in BIDS (2008 R2) stays blank during the process operation and how I need to click on &#8220;Stop&#8221; after it finishes. The fact that such a bug had gotten into the product and has survived for so long when it happens 80-90% of the time doesn&#8217;t speak very well for the QA process at Microsoft. However, I can understand that the impact of this bug would have been deemed very insignificant as it impacts developers only and does not prevent them from doing their job. By the way, if you are also annoyed by the blank process dialog in the latest version of SQL Server, you will have to wait until the next release (2012) until you get a fix:</p>
<p><a href="http://connect.microsoft.com/SQLServer/feedback/details/536543/ssas-process-progress-window-blank-no-details">http://connect.microsoft.com/SQLServer/feedback/details/536543/ssas-process-progress-window-blank-no-details</a></p>
<p>The other bug is far more significant. It not only impair developers&#8217; ability to build some features, but is also highly visible to all Excel users. However, it is hard(er) to reproduce:</p>
<p><a href="http://connect.microsoft.com/SQLServer/feedback/details/484146/getting-an-error-when-trying-to-browse-a-cube">http://connect.microsoft.com/SQLServer/feedback/details/484146/getting-an-error-when-trying-to-browse-a-cube</a></p>
<p>Still, it seems like developers from {[World].[Countries].Members}-{[World].[Countries].[USA]} hit it all the time. I am speaking about the Locale Identifier bug. The most common occurrence is when drilling through to detail in Excel. After the drill-through action has been initiated, Excel shows a message box with a message talking about the XML Parser and how the Locale Identifier cannot be overwritten -</p>
<p><strong>&#8220;XML for Analysis parser: The LocaleIdentifier property is not overwritable and cannot be assigned a new value.&#8221;</strong></p>
<p>The cause is simple (as confirmed by the SSAS team at Microsoft and Akshai Mirchandani in particular): once we open a session we cannot overwrite the locale. The mystery is around the cause for Excel to do something like that. Noting that Excel is not the only offender, as I have also seen the same error message thrown by SQL Server Profiler, and <a href="http://cwebbbi.wordpress.com/">Chris Webb </a>has seen it with the Cube Browser in BIDS:</p>
<p><a href="http://connect.microsoft.com/SQLServer/feedback/details/484146/getting-an-error-when-trying-to-browse-a-cube">http://connect.microsoft.com/SQLServer/feedback/details/484146/getting-an-error-when-trying-to-browse-a-cube</a></p>
<p>Since the bug has been reported to Microsoft, we are now hopeful that a fix will appear at some point. Until then you can try the following workaround, courtesy of my friends and former colleagues Matthew Ward and Paul Hales:</p>
<p>- Switch the Windows Region and Language Format in Control Panel to English (United States):</p>
<p><a href="http://www.bp-msbi.com/wp-content/uploads/2012/01/region_language_format.png"><img class="size-full wp-image-473 alignnone" title="region_language_format" src="http://www.bp-msbi.com/wp-content/uploads/2012/01/region_language_format.png" alt="" width="477" height="550" /></a></p>
<p>- Switch it back to whatever it was before</p>
<p>Now the &#8220;bug&#8221; should be fixed for that machine. For example, I had my new Windows 7 workstation configured to use Australian formats. After I got the Locale Identifier error message in Profiler, I switched the formats to USA. The bug disappeared and I could profile SSAS. After that I switched Windows back to the original English (Australia) format&#8230;and nothing broke. I could still use Profiler and drill-through in Excel.</p>
<p>Another notice. <a href="http://www.artisconsulting.com/blogs/greggalloway/default.aspx">Greg Galloway </a>has released a new version (0.7.4) of the <a href="http://olappivottableextend.codeplex.com/releases/view/81169">OLAP Pivot Extensions add-in for Excel</a>. In case you have been experiencing a Locale Identifier problem in SSAS while using older versions of the add-in, please download the new one and let Greg know (e.g. on the <a href="http://olappivottableextend.codeplex.com/discussions">discussions page</a> on CodePlex) if the new release fies your problem.</p>
<p>Thanks to everyone involved in confirming and testing different fixes. Ideally, I would like to see Microsoft fixing this on the server side of things which would allow us to easily patch up all existing systems exhibiting the problem.</p>
<p>Since all Microsoft Connect item related to this bug have been closed, I opened a new one, so you can vote in order to prioritise this issue:</p>
<p><a href="https://connect.microsoft.com/SQLServer/feedback/details/721372/locale-identifier-bug">https://connect.microsoft.com/SQLServer/feedback/details/721372/locale-identifier-bug</a></p>
<p>&nbsp;</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/bp-msbi?a=lmJMCnPx4kg:R_zH8Na0Ycg:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/bp-msbi?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/bp-msbi?a=lmJMCnPx4kg:R_zH8Na0Ycg:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/bp-msbi?i=lmJMCnPx4kg:R_zH8Na0Ycg:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/bp-msbi?a=lmJMCnPx4kg:R_zH8Na0Ycg:YwkR-u9nhCs"><img src="http://feeds.feedburner.com/~ff/bp-msbi?d=YwkR-u9nhCs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/bp-msbi/~4/lmJMCnPx4kg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.bp-msbi.com/2012/01/ssas-locale-identifier-bug/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.bp-msbi.com/2012/01/ssas-locale-identifier-bug/</feedburner:origLink></item>
		<item>
		<title>Load Testing BI Solutions – When?</title>
		<link>http://feedproxy.google.com/~r/bp-msbi/~3/HzkoTQBcnG0/</link>
		<comments>http://www.bp-msbi.com/2011/12/load-testing-bi-solutions-when/#comments</comments>
		<pubDate>Fri, 23 Dec 2011 23:58:56 +0000</pubDate>
		<dc:creator>Boyan Penev</dc:creator>
				<category><![CDATA[Other]]></category>
		<category><![CDATA[Load Testing]]></category>

		<guid isPermaLink="false">http://www.bp-msbi.com/?p=470</guid>
		<description><![CDATA[This year I came across two very different BI projects which had the common non-functional requirement to prove that they would handle an expected spike in the report generation load. Funny enough, in both cases the project teams got very concerned and came up with wildly inaccurate predictions of how many concurrent users we should [...]]]></description>
			<content:encoded><![CDATA[<p>This year I came across two very different BI projects which had the common non-functional requirement to prove that they would handle an expected spike in the report generation load. Funny enough, in both cases the project teams got very concerned and came up with wildly inaccurate predictions of how many concurrent users we should be testing for. In the first case the problem was with the perception of “thousands of users”, while in the second, the team interpreted “monthly users” as “concurrent users”. The annoying part was that in the first case the team planned on building an ultra-massively overcomplicated queuing system to handle those spikes, and in the second case they were thinking of completely scrapping the ad-hoc functionality in the solution and resorting to report extracts distributed by email. The unreasonable expectations of the load lead to bad design choices – this is why it is important to <strong>remain calm and first check whether there is a problem at all.</strong></p>
<p>Firstly, let’s agree that we are measuring report requests. To begin, we should know how many requests we get per a period of time (e.g. a month), and then how long it takes to generate a report. A typical scenario would be:</p>
<ul>
<li>1,000,000 report requests per month</li>
<li>2 seconds to generate a report on average</li>
</ul>
<p>What we need to do now if apply a bit of math:</p>
<p>1,000,000 / 20 = 50,000 requests per day (on average)</p>
<p>50,000 / 8 = 6,250 requests per hour (8 hours in a working day)</p>
<p>Since a report takes 2 seconds to generate, we can generate 1,800 reports in one hour. Therefore, with 6,250 requests, we would have 3.47 average concurrent users. Of course, this would be the case if we have a very uniformly split load. In reality this would not happen – instead, we will have peaks and dips in usage. A moderate peak is typically around 3x the average, while a heavy one would be at around 6x the average. To ensure that we can handle such peak periods, we should multiply our average concurrent users by 3 or by 6 depending on our load analysis. Let’s assume we have a very high peak load of 3.47 * 6 = 20.82, or approximately 21 concurrent users. This is the number we need to test in our case. Note that we had 1,000,000 report requests per month, but in our highest peak we expect to have only 21 concurrent users. I have not actually had a project where we have expected to have such a load (in both cases which prompted me to write this post we had between 2000-10000 users per month).</p>
<p>The moral of the story – don’t panic. In most reporting projects the user load is not high enough to warrant a full-scale load testing exercise; next time you hear talking about something like that, instead of rushing to cover unreasonable scenarios, try to calculate and confirm the need first.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/bp-msbi?a=HzkoTQBcnG0:hgrG_ZENrqc:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/bp-msbi?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/bp-msbi?a=HzkoTQBcnG0:hgrG_ZENrqc:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/bp-msbi?i=HzkoTQBcnG0:hgrG_ZENrqc:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/bp-msbi?a=HzkoTQBcnG0:hgrG_ZENrqc:YwkR-u9nhCs"><img src="http://feeds.feedburner.com/~ff/bp-msbi?d=YwkR-u9nhCs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/bp-msbi/~4/HzkoTQBcnG0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.bp-msbi.com/2011/12/load-testing-bi-solutions-when/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.bp-msbi.com/2011/12/load-testing-bi-solutions-when/</feedburner:origLink></item>
		<item>
		<title>DataMarket Updates: Speed, Portal and DateStream</title>
		<link>http://feedproxy.google.com/~r/bp-msbi/~3/lxFH-b6gv6Q/</link>
		<comments>http://www.bp-msbi.com/2011/12/datamarket-updates-speed-portal-and-datestream/#comments</comments>
		<pubDate>Thu, 08 Dec 2011 00:08:19 +0000</pubDate>
		<dc:creator>Boyan Penev</dc:creator>
				<category><![CDATA[Other]]></category>
		<category><![CDATA[DataMarket]]></category>
		<category><![CDATA[DateStream]]></category>
		<category><![CDATA[updates]]></category>

		<guid isPermaLink="false">http://www.bp-msbi.com/?p=469</guid>
		<description><![CDATA[It has been an eventful week for the Azure DataMarket. We had three new and exciting (for geeks like me) things happening in that corner of the Microsoft universe: 1. Speed! There was an update to the Azure DataMarket a few days ago. It was, in my opinion, the best thing Microsoft could have done [...]]]></description>
			<content:encoded><![CDATA[<p>It has been an eventful week for the Azure DataMarket. We had three new and exciting (for geeks like me) things happening in that corner of the Microsoft universe:</p>
<h5>1. Speed!</h5>
<p>There was an update to the Azure DataMarket a few days ago. It was, in my opinion, the best thing Microsoft could have done to their offering &#8211; tremendously increase its performance. While the DataMarket was previously plagued by unacceptably slow download speed, now it&#8217;s for feed standards blazingly fast. For comparison sake, I used to wait for more than 40 minutes when downloading an approximately 70k rows feed from the DataMarket prior to the update. Now, it is on my machine in around 5 &#8211; 8-fold increase in performance! Rumours have it that on faster-than-my-home-ADSL2+-networks we will be experiencing up to 20x better performance. It would be good to hear if this is actually correct for developers on such networks (please comment).</p>
<p>Next, range queries, hopefully&#8230;</p>
<h5>2. Portal</h5>
<p>While before the last couple of days anyone who wanted to publish data on the DataMarket had to contact the Microsoft team via email and ask how to get it done, we have just moved into the self-service space with a new portal allowing publishers to create and manage their feeds. The link to this new portal is:</p>
<p><a href="https://publish.marketplace.windowsazure.com/" class="broken_link">https://publish.marketplace.windowsazure.com/</a></p>
<p>And, you can find some very helpful documentation about it here:</p>
<p><a href="http://msdn.microsoft.com/en-us/library/windowsazure/hh563871.aspx">http://msdn.microsoft.com/en-us/library/windowsazure/hh563871.aspx</a></p>
<h5>3. DateStream</h5>
<p>Finally, I am proud to announce that the great <a href="https://datamarket.azure.com/dataset/1542c52d-d466-4094-a801-9ef8fd7c6485">DateStream </a>feed got translated in four more languages:</p>
<p>- <strong>Hebrew</strong> and <strong>Danish</strong> &#8211; thanks to <a href="http://sqlserverjedi.wordpress.com/">Rafi Asraf</a></p>
<p>- <strong>German</strong></p>
<p>- <strong>Bulgarian</strong></p>
<p>The <strong>Italian</strong> translation (thanks to <a href="http://sqlblog.com/blogs/marco_russo/">Marco Russo</a>) is coming soon too, but missed this release unfortunately.</p>
<p>Feel free to explore them and let me know if anything needs to be changed to make them more correct/useful.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/bp-msbi?a=lxFH-b6gv6Q:R47BKadQOp8:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/bp-msbi?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/bp-msbi?a=lxFH-b6gv6Q:R47BKadQOp8:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/bp-msbi?i=lxFH-b6gv6Q:R47BKadQOp8:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/bp-msbi?a=lxFH-b6gv6Q:R47BKadQOp8:YwkR-u9nhCs"><img src="http://feeds.feedburner.com/~ff/bp-msbi?d=YwkR-u9nhCs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/bp-msbi/~4/lxFH-b6gv6Q" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.bp-msbi.com/2011/12/datamarket-updates-speed-portal-and-datestream/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.bp-msbi.com/2011/12/datamarket-updates-speed-portal-and-datestream/</feedburner:origLink></item>
		<item>
		<title>SSAS: Multiple SQL Queries in ROLAP Mode</title>
		<link>http://feedproxy.google.com/~r/bp-msbi/~3/ipMOpOFUX3U/</link>
		<comments>http://www.bp-msbi.com/2011/11/ssas-multiple-sql-queries-in-rolap-mode/#comments</comments>
		<pubDate>Sun, 27 Nov 2011 13:30:37 +0000</pubDate>
		<dc:creator>Boyan Penev</dc:creator>
				<category><![CDATA[SSAS]]></category>
		<category><![CDATA[error]]></category>
		<category><![CDATA[referential integrity]]></category>
		<category><![CDATA[ROLAP]]></category>

		<guid isPermaLink="false">http://www.bp-msbi.com/?p=457</guid>
		<description><![CDATA[Just recently I was working on a project where I had to build a SSAS ROLAP cube on top of a badly built data mart. Badly built in this case meant one where we encounter multiple referential integrity (RI) issues. Most importantly, the designers ignored the very basic principle that all dimension keys for each [...]]]></description>
			<content:encoded><![CDATA[<p>Just recently I was working on a project where I had to build a SSAS ROLAP cube on top of a badly built data mart. Badly built in this case meant one where we encounter multiple referential integrity (RI) issues. Most importantly, the designers ignored the very basic principle that all dimension keys for each row must be present in the respective dimension tables. When in MOLAP mode, SSAS checks for such mismatches during processing. However, when a partition is in ROLAP storage mode, we don&#8217;t get a notification that anything is wrong and the cube processing operation succeeds. This situation has some consequences during execution time and I will try to illustrate those in this post and show a solution. Before I begin, I must say that if it wasn&#8217;t for Akshai Mirchandani&#8217;s (from the Microsoft SSAS dev team) and <a href="http://www.artisconsulting.com/blogs/greggalloway/default.aspx">Greg Galloway</a>&#8216;s help, I would have probably spent quite some time figuring out what is happening. Thanks to them the problem got solved quickly and I got to understand the reason for what is happening.</p>
<p>In terms of set-up, I created two tables in SQL Server: Dim and Fact. The Dim table contained two members A and B, with keys of 1 and 2. Initially, the Fact table had two rows referencing the Dim table &#8211; Dim keys of 1 and 2, and a measure column called Amount with 1.0 and 2.0 as the amounts corresponding to A and B. No issues here. After that I created a SSAS solution, corresponding to this simple dimensional model. I switched the partition storage for the cube to ROLAP and processed the SSAS database. After that I ran the following query, which I used for all subsequent examples:</p>
<p><a href="http://www.bp-msbi.com/wp-content/uploads/2011/11/00_query.png"><img class="alignleft size-full wp-image-458" title="00_query" src="http://www.bp-msbi.com/wp-content/uploads/2011/11/00_query.png" alt="" width="190" height="139" /></a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>The result was as expected:</p>
<p><a href="http://www.bp-msbi.com/wp-content/uploads/2011/11/04_good_ri_result.png"><img class="alignleft size-full wp-image-459" title="04_good_ri_result" src="http://www.bp-msbi.com/wp-content/uploads/2011/11/04_good_ri_result.png" alt="" width="81" height="57" /></a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>At the same time I had a SQL Server Profiler trace running, which showed:</p>
<p><a href="http://www.bp-msbi.com/wp-content/uploads/2011/11/01_good_ri_trace.png"><img class="alignleft size-full wp-image-460" title="01_good_ri_trace" src="http://www.bp-msbi.com/wp-content/uploads/2011/11/01_good_ri_trace.png" alt="" width="889" height="163" /></a></p>
<p>&nbsp;</p>
<p>We can see that SSAS has executed one SQL query retrieving data from the fact table. Nothing unusual thus far.</p>
<p>To spoil the party, I added one more row to the fact table with a dimension key of 3 and Amount of 3. Since I did not add a row in the dimension table with a key of 3, this broke the rules and if I had a foreign key constraint implemented between the fact and the dimension tables I would not have been able to do this. After cleaning the SSAS cache, I ran my query again. The result:</p>
<p><a href="http://www.bp-msbi.com/wp-content/uploads/2011/11/03_bad_ri_result.png"><img class="alignleft size-full wp-image-461" title="03_bad_ri_result" src="http://www.bp-msbi.com/wp-content/uploads/2011/11/03_bad_ri_result.png" alt="" width="79" height="58" /></a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>The actual error was, of course, a missing key. I was not surprised when I saw this on my original project. However, looking at Profiler we see a &#8220;weird&#8221; sequence of events:</p>
<p><a href="http://www.bp-msbi.com/wp-content/uploads/2011/11/02_bad_ri_trace.png"><img class="alignleft size-full wp-image-462" title="02_bad_ri_trace" src="http://www.bp-msbi.com/wp-content/uploads/2011/11/02_bad_ri_trace.png" alt="" width="890" height="484" /></a></p>
<p>&nbsp;</p>
<p>SSAS runs multiple queries which result in errors. In this case we can see four of these ExecuteSQL events. All of them are followed by an error in a ReadData event. In this particular case we can see only four ExecuteSQL events. In the real-world, this scenario can get multiple times worse (in my case we saw 4667 queries run against the relational database in a few minutes) leading to a really significant drop in performance.</p>
<p>So, what is happening? According to Akshai, SSAS encounters an error while dealing with the results from the initial SQL query and is trying to recover by sending more queries. In some cases this can result in getting the error in the result set only for some cells.</p>
<p>Luckily, there is an easy way out of this situation (thanks to Greg for providing the tips). SSAS can automatically create an &#8220;unknown bucket&#8221; for each dimension and can assign to it all measure values which do not correspond to a dimension member. To get this result, we must ensure that each affected partition&#8217;s error configuration is set to something similar to:</p>
<p><a href="http://www.bp-msbi.com/wp-content/uploads/2011/11/05_default_partition_error_config.png"><img class="alignleft size-full wp-image-463" title="05_default_partition_error_config" src="http://www.bp-msbi.com/wp-content/uploads/2011/11/05_default_partition_error_config.png" alt="" width="378" height="278" /></a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>Note that the KeyErrorAction is ConvertToUnknown, not DiscardRecord (which is the alternative). This must also be coupled with setting up each &#8220;incomplete&#8221; dimension to include an Unknown member:</p>
<p><a href="http://www.bp-msbi.com/wp-content/uploads/2011/11/07_dim_with_unknown.png"><img class="alignleft size-full wp-image-464" title="07_dim_with_unknown" src="http://www.bp-msbi.com/wp-content/uploads/2011/11/07_dim_with_unknown.png" alt="" width="383" height="308" /></a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>It does not matter whether the UnknownMember is Visible or Hidden, as long as it is not None.</p>
<p>Back to our scenario. After setting these properties on the dimension and the partition I processed the SSAS database again and executed the query. The result:</p>
<p><a href="http://www.bp-msbi.com/wp-content/uploads/2011/11/09_result_with_unknown.png"><img class="alignleft size-full wp-image-465" title="09_result_with_unknown" src="http://www.bp-msbi.com/wp-content/uploads/2011/11/09_result_with_unknown.png" alt="" width="182" height="79" /></a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>and the profiler trace:</p>
<p><a href="http://www.bp-msbi.com/wp-content/uploads/2011/11/08_trace_with_unknown.png"><img class="alignleft size-full wp-image-466" title="08_trace_with_unknown" src="http://www.bp-msbi.com/wp-content/uploads/2011/11/08_trace_with_unknown.png" alt="" width="933" height="166" /></a></p>
<p>&nbsp;</p>
<p>As we can see we eliminated the multiple queries. If we do not want to see the Unknown amount in the cube we can use a scope assignment:</p>
<p><a href="http://www.bp-msbi.com/wp-content/uploads/2011/11/10_scope.png"><img class="alignleft size-full wp-image-467" title="10_scope" src="http://www.bp-msbi.com/wp-content/uploads/2011/11/10_scope.png" alt="" width="270" height="51" /></a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>Coupled with making the UnknownMember Hidden, we can completely obliterate traces of our underlying RI issues. Unless our users check the numbers, but then we can blame whoever designed the datamart! :)</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/bp-msbi?a=ipMOpOFUX3U:A3ilYJud10Y:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/bp-msbi?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/bp-msbi?a=ipMOpOFUX3U:A3ilYJud10Y:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/bp-msbi?i=ipMOpOFUX3U:A3ilYJud10Y:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/bp-msbi?a=ipMOpOFUX3U:A3ilYJud10Y:YwkR-u9nhCs"><img src="http://feeds.feedburner.com/~ff/bp-msbi?d=YwkR-u9nhCs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/bp-msbi/~4/ipMOpOFUX3U" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.bp-msbi.com/2011/11/ssas-multiple-sql-queries-in-rolap-mode/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.bp-msbi.com/2011/11/ssas-multiple-sql-queries-in-rolap-mode/</feedburner:origLink></item>
		<item>
		<title>Melbourne SQL Server Social Event: Short Notice!</title>
		<link>http://feedproxy.google.com/~r/bp-msbi/~3/_O15chMARx4/</link>
		<comments>http://www.bp-msbi.com/2011/11/melbourne-sql-server-social-event-short-notice/#comments</comments>
		<pubDate>Tue, 15 Nov 2011 23:59:55 +0000</pubDate>
		<dc:creator>Boyan Penev</dc:creator>
				<category><![CDATA[Other]]></category>
		<category><![CDATA[event]]></category>
		<category><![CDATA[SQL Server]]></category>

		<guid isPermaLink="false">http://www.bp-msbi.com/?p=454</guid>
		<description><![CDATA[A short notice for SQL Server enthusiasts/professionals in Melbourne. Stephen Few is in town and will attend the SQL Server Social Event tomorrow (17 Nov) at the Sherlock Holmes Inn in the CBD (415 Collins Street). Feel free to come and meet the community, talk about SQL Server and information visualisation..and possibly get your Stephen [...]]]></description>
			<content:encoded><![CDATA[<p>A short notice for SQL Server enthusiasts/professionals in Melbourne. <a href="http://www.perceptualedge.com/">Stephen Few</a> is in town and will attend the SQL Server Social Event tomorrow (17 Nov) at the Sherlock Holmes Inn in the CBD (415 Collins Street). Feel free to come and meet the community, talk about SQL Server and information visualisation..and possibly get your Stephen Few books signed.</p>
<p>Link for the event: <a href="http://sqlserversocial.eventbrite.com/">http://sqlserversocial.eventbrite.com/</a></p>
<p>See you there!</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/bp-msbi?a=_O15chMARx4:YKxFJ-Vi9uI:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/bp-msbi?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/bp-msbi?a=_O15chMARx4:YKxFJ-Vi9uI:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/bp-msbi?i=_O15chMARx4:YKxFJ-Vi9uI:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/bp-msbi?a=_O15chMARx4:YKxFJ-Vi9uI:YwkR-u9nhCs"><img src="http://feeds.feedburner.com/~ff/bp-msbi?d=YwkR-u9nhCs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/bp-msbi/~4/_O15chMARx4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.bp-msbi.com/2011/11/melbourne-sql-server-social-event-short-notice/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.bp-msbi.com/2011/11/melbourne-sql-server-social-event-short-notice/</feedburner:origLink></item>
		<item>
		<title>Alternate Ordering of Attributes in SSAS</title>
		<link>http://feedproxy.google.com/~r/bp-msbi/~3/FV55GdNTFIc/</link>
		<comments>http://www.bp-msbi.com/2011/11/alternate-ordering-of-attributes-in-ssas/#comments</comments>
		<pubDate>Sat, 05 Nov 2011 11:30:38 +0000</pubDate>
		<dc:creator>Boyan Penev</dc:creator>
				<category><![CDATA[SSAS]]></category>
		<category><![CDATA[dimension]]></category>
		<category><![CDATA[ordering]]></category>

		<guid isPermaLink="false">http://www.bp-msbi.com/?p=445</guid>
		<description><![CDATA[Sometimes we need to display attribute members in SSAS in a different order than the order of its name or key. For this purpose we have the option to use one of its attribute&#8217;s name or key. However, in some cases changing the order may break some calculation logic which depends on the initial order. [...]]]></description>
			<content:encoded><![CDATA[<p>Sometimes we need to display attribute members in SSAS in a different order than the order of its name or key. For this purpose we have the option to use one of its attribute&#8217;s name or key. However, in some cases changing the order may break some calculation logic which depends on the initial order. The new ordering may also be inconvenient for writing MDX as using some functions of the language is easier (at least conceptually) when thinking of sets in ascending order. The best example which we can use to illustrate this problem is the Date dimension. While in most, if not all, cases the Date dimension is ordered in ascending order, sometimes users prefer to see the most recent date first and request us to change the order to descending. Doing so invalidates many time intelligence calculations like rolling and parallel periods, etc. Furthermore, fixing those requires inverting numbers to negative, or avoiding the use of functions like ClosingPeriod. All in all, a &#8220;small&#8221; change can lead to a big problem. We can, however, accommodate our ignorant users (which unknowingly get the benefit of <a href="http://jsimonbi.wordpress.com/2011/11/19/date-order/">reading default time series charts backwards</a> – from right to left – when dragging-dropping descending dates in Excel, for example) without changing too much in our scripts. A little trick in the modelling can help and it is the reason for writing this post.</p>
<p>Let&#8217;s have a look at a simple Date dimension with one attribute – Date. Nothing unusual, with the Date being ordered by its Key (integer in this case) and with a name coming from another column in the Date table – DateName. When we create a simple slice in Excel we get the following:</p>
<p><a href="http://www.bp-msbi.com/wp-content/uploads/2011/11/alt-order-01.png"><img class="alignleft size-full wp-image-446" title="alt-order-01" src="http://www.bp-msbi.com/wp-content/uploads/2011/11/alt-order-01.png" alt="" width="169" height="241" /></a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>Now we create a measure Rolling 3 Days Amount, which sums the last 3 days&#8217; amount:</p>
<p><a href="http://www.bp-msbi.com/wp-content/uploads/2011/11/alt-order-02.png"><img class="alignleft size-full wp-image-447" title="alt-order-02" src="http://www.bp-msbi.com/wp-content/uploads/2011/11/alt-order-02.png" alt="" width="314" height="238" /></a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>The MDX for this calculation is:</p>
<p><a href="http://www.bp-msbi.com/wp-content/uploads/2011/11/alt-order-03.png"><img class="alignleft size-full wp-image-448" title="alt-order-03" src="http://www.bp-msbi.com/wp-content/uploads/2011/11/alt-order-03.png" alt="" width="512" height="101" /></a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>If we simply invert the order of the Date attribute by ordering it by another column in our Date table, which contains DateKey*-1 and refresh the Excel pivot table we get the following:</p>
<p><a href="http://www.bp-msbi.com/wp-content/uploads/2011/11/alt-order-04.png"><img class="alignleft size-full wp-image-449" title="alt-order-04" src="http://www.bp-msbi.com/wp-content/uploads/2011/11/alt-order-04.png" alt="" width="316" height="221" /></a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>This is simply incorrect. A relatively small change in the MDX script can help us with this issue (e.g. changing the Lag to Lead), however in many cases we do not want to rebuild all the measures. Luckily, we can employ a different tactic. Instead of changing the script, we can change the structure of our dimension by adding an additional attribute which is not exposed to the users. (i.e. is hidden). This attribute will be based on the same column we use for our Date, but will not be ordered by the descending column. We can rename the original attribute (the one exposed to the users) to something like Date Desc, or a more user-friendly option, and hide the new one:</p>
<p><a href="http://www.bp-msbi.com/wp-content/uploads/2011/11/alt-order-05.png"><img class="alignleft size-full wp-image-450" title="alt-order-05" src="http://www.bp-msbi.com/wp-content/uploads/2011/11/alt-order-05.png" alt="" width="153" height="69" /></a>         <a href="http://www.bp-msbi.com/wp-content/uploads/2011/11/alt-order-06.png"><img class="alignleft size-full wp-image-451" title="alt-order-06" src="http://www.bp-msbi.com/wp-content/uploads/2011/11/alt-order-06.png" alt="" width="160" height="71" /></a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>Everything else stays the same – our cube script does not need to be adjusted and its logic is correct:</p>
<p><a href="http://www.bp-msbi.com/wp-content/uploads/2011/11/alt-order-07.png"><img class="alignleft size-full wp-image-452" title="alt-order-07" src="http://www.bp-msbi.com/wp-content/uploads/2011/11/alt-order-07.png" alt="" width="314" height="240" /></a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>A different approach could be to leave the old attribute named Date, so there is no change necessary in case of reports depending on the naming. This, however, requires a change of the cube script, which can be easily performed with using the BIDS Replace functionality (e.g. Ctrl+H).</p>
<p>Note that for this approach to work we need to make sure that the attribute exposed to the users is the dimension key attribute as changing its current member results in an (infamous) attribute overwrite where its related attributes, which are above it in the relationship chain) also change. If we expose the non-key date attribute our MDX logic will break as the changes to its current member will not affect the attributes below it (actually, it will set them to their All member).</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/bp-msbi?a=FV55GdNTFIc:NyJj_VilFUs:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/bp-msbi?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/bp-msbi?a=FV55GdNTFIc:NyJj_VilFUs:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/bp-msbi?i=FV55GdNTFIc:NyJj_VilFUs:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/bp-msbi?a=FV55GdNTFIc:NyJj_VilFUs:YwkR-u9nhCs"><img src="http://feeds.feedburner.com/~ff/bp-msbi?d=YwkR-u9nhCs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/bp-msbi/~4/FV55GdNTFIc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.bp-msbi.com/2011/11/alternate-ordering-of-attributes-in-ssas/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.bp-msbi.com/2011/11/alternate-ordering-of-attributes-in-ssas/</feedburner:origLink></item>
		<item>
		<title>Range Queries with Azure DataMarket Feeds</title>
		<link>http://feedproxy.google.com/~r/bp-msbi/~3/xH-eXLsCyTo/</link>
		<comments>http://www.bp-msbi.com/2011/10/range-queries-with-azure-datamarket-feeds/#comments</comments>
		<pubDate>Mon, 17 Oct 2011 03:32:45 +0000</pubDate>
		<dc:creator>Boyan Penev</dc:creator>
				<category><![CDATA[PowerPivot]]></category>
		<category><![CDATA[DataMarket]]></category>
		<category><![CDATA[DateStream]]></category>
		<category><![CDATA[feeds]]></category>
		<category><![CDATA[OData]]></category>

		<guid isPermaLink="false">http://www.bp-msbi.com/?p=441</guid>
		<description><![CDATA[By default the Azure DataMarket does not allow range queries. In fact, the only way we can filter a data feed is through specifying one or more values for the &#8220;queryable&#8221; fields specified for it. There is not technical reason behind not allowing range queries as both the back-end (presumably SQL Azure, or SQL Server) [...]]]></description>
			<content:encoded><![CDATA[<p>By default the Azure DataMarket does not allow range queries. In fact, the only way we can filter a data feed is through specifying one or more values for the &#8220;queryable&#8221; fields specified for it. There is not technical reason behind not allowing range queries as both the back-end (presumably SQL Azure, or SQL Server) and the OData protocol support them. Fortunately, there is a way to consume a range of the values in a column of a data feed in PowerPivot. It is not straight-forward and I do not think that the target audience of both self-service BI/PowerPivot and the DataMarket itself would appreciate the complexity, but it could be useful anyway.</p>
<p>If we want to pull all three tables from the DataMarket we can simply use <strong><span style="color: #800000;">https://api.datamarket.azure.com/BoyanPenev/DateStream/</span></strong> as the URL in PowerPivot:</p>
<p><a href="http://www.bp-msbi.com/wp-content/uploads/2011/10/ppvt-query-01.png"><img class="alignleft size-full wp-image-442" title="PowerPivot full feed query" src="http://www.bp-msbi.com/wp-content/uploads/2011/10/ppvt-query-01.png" alt="" width="532" height="544" /></a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>Otherwise, we can pick each one with a URL like (for the BasicCalendarEngish table):</p>
<p><strong><span style="color: #800000;">https://api.datamarket.azure.com/Data.ashx/BoyanPenev/DateStream/BasicCalendarEnglish</span></strong></p>
<p>If we filter the data set on the DataMarket website to request only the data for 2010 we get the following URL:</p>
<p><span style="color: #800000;"><strong>https://api.datamarket.azure.com/Data.ashx/BoyanPenev/DateStream/BasicCalendarEnglish?$filter=YearKey%20eq%202010</strong></span></p>
<p>Note the last bit:</p>
<p><strong><span style="color: #800000;">?$filter=YearKey%20eq%202010</span></strong></p>
<p>This is simply the URL/OData encoded <strong><span style="color: #800000;">?$filter=YearKey = 2010</span></strong></p>
<p>In OData we can also use other operators, not just = (or <strong><span style="color: #ff0000;">eq</span></strong>). For ranges these are <span style="color: #ff0000;"><strong>gt</strong></span> (greater than), <span style="color: #ff0000;"><strong>ge</strong></span> (greater than or equal to), <span style="color: #ff0000;"><strong>lt</strong></span> (less than) and <span style="color: #ff0000;"><strong>le</strong></span> (less than or equal to). We can also use <span style="color: #ff0000;"><strong>and</strong></span> and <span style="color: #ff0000;"><strong>or</strong></span> operators to combine different predicates. For a more thorough list, please refer to <a href="http://www.odata.org/developers/protocols/uri-conventions">http://www.odata.org/developers/protocols/uri-conventions</a>. If we replace the &#8221; = 2010&#8243; with &#8221; &lt; 2010&#8243; and then encode the URL, we do indeed get all years prior to 2010. Things get slightly more complicated when we have a more complex scenario. In example, when building a date table we may want to include all years between 2000 and 2030. To do that, we would have to write something like:</p>
<p><span style="color: #800000;"><strong>https://api.datamarket.azure.com/Data.ashx/BoyanPenev/DateStream/BasicCalendarEnglish?$filter=<span style="color: #000080;">YearKey &gt;= 2000 and YearKey &lt;= 2030</span></strong></span></p>
<p>encoded, the same looks like this:</p>
<p><span style="color: #800000;"><strong>https://api.datamarket.azure.com/Data.ashx/BoyanPenev/DateStream/BasicCalendarEnglish?$filter=<span style="color: #000080;">YearKey<span style="color: #33cccc;">%20</span><span style="color: #ff0000;">ge</span><span style="color: #33cccc;">%20</span>2000<span style="color: #33cccc;">%20</span><span style="color: #ff0000;">and</span><span style="color: #33cccc;">%20</span>YearKey<span style="color: #33cccc;">%20</span><span style="color: #ff0000;">le</span><span style="color: #33cccc;">%20</span>2030</span></strong></span></p>
<p>Here <span style="color: #33cccc;"><strong>space</strong></span> is <span style="color: #33cccc;"><strong>%20</strong><span style="color: #000000;"> and the math comparison operators have been replaced with the OData operators (in <span style="color: #ff0000;">red</span>)</span></span>.</p>
<p>If we paste this in PowerPivot and hit &#8220;Next&#8221;:</p>
<p><a href="http://www.bp-msbi.com/wp-content/uploads/2011/10/ppvt-query-021.png"><img class="alignleft size-full wp-image-444" title="PowerPivot filtered feed" src="http://www.bp-msbi.com/wp-content/uploads/2011/10/ppvt-query-021.png" alt="" width="532" height="544" /></a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>…we get exactly what we expect – a table with 30 years.</p>
<p>Things get more complicated if we include the datetime DateKey in the URL. For a single date (e.g. 1900-01-01), we have to use:</p>
<p><span style="color: #800000;"><strong>https://api.datamarket.azure.com/Data.ashx/BoyanPenev/DateStream/BasicCalendarEnglish?$filter=<span style="color: #000080;">DateKey = datetime&#8217;1900-01-01T00:00:00&#8242;</span></strong></span></p>
<p>After Applying URL encoding we get:</p>
<p><span style="color: #800000;"><strong>https://api.datamarket.azure.com/Data.ashx/BoyanPenev/DateStream/BasicCalendarEnglish?$filter=<span style="color: #000080;">DateKey<span style="color: #33cccc;">%20</span><span style="color: #ff0000;">eq</span><span style="color: #33cccc;">%20</span>datetime<span style="color: #33cccc;">%27</span>1900-01-01T00<span style="color: #33cccc;">%3a</span>00<span style="color: #33cccc;">%3a</span>00<span style="color: #33cccc;">%27</span></span></strong></span></p>
<p>Where<span style="color: #33cccc;"> %27</span> is <span style="color: #33cccc;">apostrophe <span style="color: #000000;">and</span></span> <span style="color: #33cccc;">%3a</span> is a <span style="color: #33cccc;">colon</span> (for a list of ASCII characters and their URL encoded form we can refer to <a href="http://www.w3schools.com/tags/ref_urlencode.asp">http://www.w3schools.com/tags/ref_urlencode.asp).</a></p>
<p>Now, to combine the two we would need to write:</p>
<p><span style="color: #800000;"><strong>https://api.datamarket.azure.com/Data.ashx/BoyanPenev/DateStream/BasicCalendarEnglish?$filter=<span style="color: #000080;">DateKey = datetime&#8217;1900-01-01T00:00:00&#8242; or (YearKey &gt;= 2000 and YearKey &lt;= 2030)</span></strong></span></p>
<p><span style="color: #000000;">Encoded this becomes:</span></p>
<p><span style="color: #800000;"><strong>https://api.datamarket.azure.com/Data.ashx/BoyanPenev/DateStream/BasicCalendarEnglish?$filter=<span style="color: #000080;">DateKey<span style="color: #33cccc;">%20</span><span style="color: #ff0000;">eq</span><span style="color: #33cccc;">%20</span>datetime<span style="color: #33cccc;">%27</span>1900-01-01T00<span style="color: #33cccc;">%3a</span>00<span style="color: #33cccc;">%3a</span>00<span style="color: #33cccc;">%27%20</span><span style="color: #ff0000;">or</span><span style="color: #33cccc;">%20%28</span>YearKey<span style="color: #33cccc;">%20</span><span style="color: #ff0000;">ge</span><span style="color: #33cccc;">%20</span>2000<span style="color: #33cccc;">%20</span><span style="color: #ff0000;">and</span><span style="color: #33cccc;">%20</span>YearKey<span style="color: #33cccc;">%20</span><span style="color: #ff0000;">le</span><span style="color: #33cccc;">%20</span>2030<span style="color: #33cccc;">%29</span></span></strong></span></p>
<p>This monstrous-to-write URL string returns 30 years of data + 1 day.</p>
<p>I suppose this approach can be classified as a workaround, as I have not seen any documentation on PowerPivot referring to any options for filtering data from the Azure DataMarket. However, in my opinion, this should be a feature of the DataMarket itself as it would make it easier/possible for users with any tool to get just the data they need and even possibly reduce the load on the site service since it will no longer be necessary to export everything and then attempt to apply a filter.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/bp-msbi?a=xH-eXLsCyTo:7tONrjFj1tI:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/bp-msbi?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/bp-msbi?a=xH-eXLsCyTo:7tONrjFj1tI:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/bp-msbi?i=xH-eXLsCyTo:7tONrjFj1tI:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/bp-msbi?a=xH-eXLsCyTo:7tONrjFj1tI:YwkR-u9nhCs"><img src="http://feeds.feedburner.com/~ff/bp-msbi?d=YwkR-u9nhCs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/bp-msbi/~4/xH-eXLsCyTo" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.bp-msbi.com/2011/10/range-queries-with-azure-datamarket-feeds/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.bp-msbi.com/2011/10/range-queries-with-azure-datamarket-feeds/</feedburner:origLink></item>
		<item>
		<title>Introducing Project DateStream (CodePlex)</title>
		<link>http://feedproxy.google.com/~r/bp-msbi/~3/aX2FRRINoWk/</link>
		<comments>http://www.bp-msbi.com/2011/10/introducing-project-datestream-codeplex/#comments</comments>
		<pubDate>Thu, 06 Oct 2011 08:02:13 +0000</pubDate>
		<dc:creator>Boyan Penev</dc:creator>
				<category><![CDATA[PowerPivot]]></category>
		<category><![CDATA[Azure DataMarket]]></category>
		<category><![CDATA[date]]></category>
		<category><![CDATA[DateStream]]></category>
		<category><![CDATA[table]]></category>

		<guid isPermaLink="false">http://www.bp-msbi.com/?p=436</guid>
		<description><![CDATA[I recently blogged about The Case for an Azure DataMarket Date Table. I finished the blog post with a bit of a critique of the DataMarket team at Microsoft, which I can now wholeheartedly apologise for. This is because since my last post I was contacted by Max Uritsky who is a Group Program Manager [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.bp-msbi.com/wp-content/uploads/2011/10/feed-02.png"><img class="alignleft size-full wp-image-438" title="feed-02" src="http://www.bp-msbi.com/wp-content/uploads/2011/10/feed-02.png" alt="" width="201" height="152" /></a>I recently blogged about <a href="http://www.bp-msbi.com/2011/06/the-case-for-an-azure-datamarket-date-table/">The Case for an Azure DataMarket Date Table</a>. I finished the blog post with a bit of a critique of the DataMarket team at Microsoft, which I can now wholeheartedly apologise for. This is because since my last post I was contacted by Max Uritsky who is a Group Program Manager on the Windows Azure Marketplace DataMarket team (a long name for a team, yes). He and Belinda Tiberio managed to help me with creating and hosting a new Date feed. Not only they helped with making it available for free on the DataMarket website, but also gave me a 1Gb free SQL Azure database for the project. A big &#8220;thank you&#8221; goes to Julie Strauss from the SSAS team for making the contact, as well.</p>
<p>To summarise, the DateStream project is a free date table available as a feed and intended to be used by PowerPivot BI users. As most, if not all, BI projects include a date table, the goal is to provide an easy-to-use, correct and simple mechanism for creating such tables.</p>
<p>After some deliberations on the format of the feed we decided that it would be best to split the feed in a number of localised Basic tables and one Extended table. Currently we have only two Basic (US and EN) versions and a fairly straight-forward Extended one. However, the plan is to inlclude more and more column in the Extended one and provide extra localised (Italian, French, Spanish, German, Russian, etc.) tables. When I am saying &#8220;we&#8221; I mean fellow SSAS professionals, which I had the pleasure to discuss this idea (among which <a href="http://sqlblog.com/blogs/marco_russo/">Marco Russo</a>, <a href="http://blog.kejser.org/">Thomas Kejser</a>, <a href="http://www.wfaerber.de/">Willfried Faerber </a>and <a href="http://www.angrykoala.com/_webapp_689/Grant_Paisley">Grant Paisley</a>).</p>
<p>The CodePlex page of the project contains more details about the feed and the tables and also allows for commenting on existing features, as well as requesting new ones. It can be found at <a href="http://datestream.codeplex.com/">http://datestream.codeplex.com/</a>.</p>
<p>The actual feed can be used directly from <a href="https://datamarket.azure.com/dataset/1542c52d-d466-4094-a801-9ef8fd7c6485">https://datamarket.azure.com/dataset/1542c52d-d466-4094-a801-9ef8fd7c6485</a>.</p>
<p>Note the logo &#8211; it was created by Daniele Perilli from<a href="http://www.sqlbi.com"> SQL BI </a>with the assistance provided by Marco Russo. Thanks to them we did not have to resort to my graphic design skills, which definitely is a win for the DataMarket website.</p>
<p>One note - please let me know if the performance you get from the feed is not satisfactory (please remember that once pulled, the feed does not need to be refreshed as the data will remain valid forever). If many people agree that it is too slow I could potentially host it on an alternative location as well. It is possible to download a CSV version from the DataMarket as a workaround, which also allows removing unnecessary date ranges.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/bp-msbi?a=aX2FRRINoWk:RzWGjYo1Zio:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/bp-msbi?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/bp-msbi?a=aX2FRRINoWk:RzWGjYo1Zio:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/bp-msbi?i=aX2FRRINoWk:RzWGjYo1Zio:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/bp-msbi?a=aX2FRRINoWk:RzWGjYo1Zio:YwkR-u9nhCs"><img src="http://feeds.feedburner.com/~ff/bp-msbi?d=YwkR-u9nhCs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/bp-msbi/~4/aX2FRRINoWk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.bp-msbi.com/2011/10/introducing-project-datestream-codeplex/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		<feedburner:origLink>http://www.bp-msbi.com/2011/10/introducing-project-datestream-codeplex/</feedburner:origLink></item>
		<item>
		<title>Two New Books Definitely Worth Buying</title>
		<link>http://feedproxy.google.com/~r/bp-msbi/~3/upGFYtdgwlI/</link>
		<comments>http://www.bp-msbi.com/2011/09/two-new-books-definitely-worth-buying/#comments</comments>
		<pubDate>Tue, 27 Sep 2011 09:55:46 +0000</pubDate>
		<dc:creator>Boyan Penev</dc:creator>
				<category><![CDATA[Other]]></category>
		<category><![CDATA[books]]></category>
		<category><![CDATA[MDX]]></category>
		<category><![CDATA[MVP Deep Dives]]></category>
		<category><![CDATA[PASS]]></category>

		<guid isPermaLink="false">http://www.bp-msbi.com/?p=430</guid>
		<description><![CDATA[I will try to provide a concise and useful insight into two books from the world of SQL Server. The first one is available now, while the second one is coming out very soon (in the next couple of weeks). MDX with Microsoft SQL Server 2008 R2 Analysis Services Cookbook (link) by Tomislav Piasevoli &#160; [...]]]></description>
			<content:encoded><![CDATA[<p>I will try to provide a concise and useful insight into two books from the world of SQL Server. The first one is available now, while the second one is coming out very soon (in the next couple of weeks).</p>
<p><a href="http://www.bp-msbi.com/wp-content/uploads/2011/09/SSAS-MDX-Cookbook.jpg"><img class="size-full wp-image-434 alignleft" title="SSAS MDX Cookbook" src="http://www.bp-msbi.com/wp-content/uploads/2011/09/SSAS-MDX-Cookbook.jpg" alt="" width="105" height="137" /></a></p>
<h5>MDX with Microsoft SQL Server 2008 R2 Analysis Services Cookbook (<a href="http://www.packtpub.com/mdx-with-microsoft-sql-server-2008-r2-analysis-services/book">link</a>)<br />
<span style="color: #888888;">by Tomislav Piasevoli</span></h5>
<p>&nbsp;</p>
<p>I received an invite to review Tomislav&#8217;s book a few weeks ago and despite the fact that I am quite busy these days, I decided to have a look mainly because I expected it to be very good as I had heard about it months ago by the author and the reviewers (Darren Gosbell, Chris Webb, Greg Galloway, Marco Russo and Deepak Puri); and because I was promised a free copy, so I wouldn&#8217;t have to buy the book myself (which I would have done anyway)<span style="font-family: Wingdings;">J</span>. Tomislav has been one of the most prominent SSAS MVPs, quite active on the MSDN Forums and writing interesting posts on his blog. I was not surprised that he has been able to deliver excellent practical advice for his readers in this cookbook and I expect to be using it often during SSAS implementations. Let&#8217;s see what you could expect from this book if you buy it.</p>
<p>Firstly, it is a cookbook – Tomislav has written recipes for a large amount of real-world scenarios. I must admit that I did not read absolutely all of them. I went through the ones I think I know well and compared Tomislav&#8217;s versions to the ones I would typically use. The topics are very well covered and follow a pattern of: Getting Ready -&gt; How to do it -&gt; How it works -&gt; There&#8217;s more -&gt; See also. First, we get an introduction, and then we prepare to get the work done. After that we get a step-by-step walkthrough for the actual solution. I liked the next section &#8220;How it works&#8221;. Here we get an explanation of why we get the result letting us get some more insight rather than blindly typing code. I find it a very nice touch and I applaud the author for spending the time to include this invaluable bit of information. The &#8220;There&#8217;s more&#8221; section after that expands a bit the topic, trying different options and showing what happens when we apply them. In the end of each chapter we have a section showing which other topics are related to the one we are currently reading. All in all, I think that Tomislav&#8217;s cookbook is very, very, well written.</p>
<p>In general, I would say that if you want to learn MDX and how it works, you can start with a textbook-style book, which shows the basics, explains them and then builds up on them. However, if you need to work with MDX now, or if you do have some knowledge but you lack practical skills, then this book is a real gem. I would definitely recommend buying Tomislav&#8217;s cookbook, and if you are interested in getting more theoretical detail on why things work the way they do, either do a lot of blog reading, or buying another MDX book to serve as a companion to this one.</p>
<p>In brief, this is the best MDX cookbook out there and offers excellent practical advice over a variety of topics.</p>
<p><a href="http://www.bp-msbi.com/wp-content/uploads/2011/09/SQL-Server-MVP-Deep-Dives.jpg"><img class="size-full wp-image-435 alignleft" title="SQL Server MVP Deep Dives vol.2" src="http://www.bp-msbi.com/wp-content/uploads/2011/09/SQL-Server-MVP-Deep-Dives.jpg" alt="" width="105" height="131" /></a></p>
<h5>MVP Deep Dives vol.2 (<a href="http://www.manning.com/delaney/">link</a>)</h5>
<p>&nbsp;</p>
<p>The second book I would like to introduce is another &#8220;must buy&#8221;. Imagine the effort required to assemble a book from 53 different authors who live in different parts of the world and are not all native English speakers (like me). Well, Kalen Delaney has made the effort…twice…and this is one of the reasons for having this book published in the next couple of weeks. Another reason is the motivation which the authors found in donating their work to <a href="http://www.operationsmile.org/">Operation Smile</a>. We are not profiting from it and we hope that you will also buy the book not only because of the outstanding content, but also because the money you spend will be used to help children with facial deformities all around the world.</p>
<p>The list of authors speaks for itself and I am very flattered to be able to participate with a chapter entitled &#8220;Managing Context in MDX&#8221;. The book will be out by the beginning of PASS Summit 2011 and there will be a book signing session, where you can get your copies signed by some of the authors. Come, drop by if you are there to say hello and have a chat!</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/bp-msbi?a=upGFYtdgwlI:-PEGTjICCCQ:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/bp-msbi?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/bp-msbi?a=upGFYtdgwlI:-PEGTjICCCQ:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/bp-msbi?i=upGFYtdgwlI:-PEGTjICCCQ:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/bp-msbi?a=upGFYtdgwlI:-PEGTjICCCQ:YwkR-u9nhCs"><img src="http://feeds.feedburner.com/~ff/bp-msbi?d=YwkR-u9nhCs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/bp-msbi/~4/upGFYtdgwlI" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.bp-msbi.com/2011/09/two-new-books-definitely-worth-buying/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.bp-msbi.com/2011/09/two-new-books-definitely-worth-buying/</feedburner:origLink></item>
		<item>
		<title>Building a Date Table</title>
		<link>http://feedproxy.google.com/~r/bp-msbi/~3/Iuob_ngkdBA/</link>
		<comments>http://www.bp-msbi.com/2011/09/building-a-date-table/#comments</comments>
		<pubDate>Mon, 19 Sep 2011 10:52:09 +0000</pubDate>
		<dc:creator>Boyan Penev</dc:creator>
				<category><![CDATA[PowerPivot]]></category>
		<category><![CDATA[SSAS]]></category>
		<category><![CDATA[dates]]></category>
		<category><![CDATA[dimensions]]></category>

		<guid isPermaLink="false">http://www.bp-msbi.com/?p=429</guid>
		<description><![CDATA[Date tables in themselves are nothing new. Every data warehouse and business intelligence project includes one of those and typically it is one of the first tables which we find on our list of implementation tasks. Surprisingly, however, I am finding that in many implementations the omnipresent date table cannot support some analytics. In this [...]]]></description>
			<content:encoded><![CDATA[<p>Date tables in themselves are nothing new. Every data warehouse and business intelligence project includes one of those and typically it is one of the first tables which we find on our list of implementation tasks. Surprisingly, however, I am finding that in many implementations the omnipresent date table cannot support some analytics. In this post I will outline a few considerations which we need to take into account when building date tables in general, and some which apply specifically to SSAS.</p>
<p><span style="color: #ff0000;">UPDATE (9th October 2011):</span> If you are a <span style="color: #008000;"><strong>PowerPivot</strong></span> user (or would not mind using an OData feed) there is a simple way to get a date/calendar table as there is a free one available on the Azure DataMarket. I recently blogged about this new project in my <a href="http://www.bp-msbi.com/2011/10/introducing-project-datestream-codeplex/">Introducing Project DateStream (CodePlex)</a> post.</p>
<p><span style="color: #ff0000;">UPDATE 2 (16 October 2011):</span> John Simon recently published a nice <a href="http://jsimonbi.wordpress.com/2011/10/09/populating-your-date-dimension/">T-SQL script which can be used to create and populate  a date table </a>on his blog. Have a look if you need one!</p>
<h5>Grain, Key and Format</h5>
<p>In general, date tables are on a daily/date grain. This is because the lowest level of reporting we need to do is very often on full days. Even if we need to analyse on time intervals smaller than a day, we should still build a Date and a Time table to support this. Why? Because if we pack it all in the same table we end up with too many rows and this is something we typically want to avoid in any dimension. As we have a row per day, one of our columns is inevitably based on the calendar date. It is also typically the dimension key. As with all other dimension tables, we need to be able to join the table to our fact tables and this is done on our key. To keep our fact tables as small as possible, we need the smallest possible data type for our keys, and in the case of a Date this is usually an integer. However, unlike with other dimensions, we do not have to have a meaningless integer for our surrogate key because it does not give us any advantage. It is very easy to convert between a datetime and an int and in SQL Server datetime is 8 bytes, while int is 4. In SQL 2008+ we have another type suitable for our date table key – date, which is 3 bytes. However, for compatibility reasons, it is frequently better to stick to an int. Luckily, we also have the very convenient ANSI/<a href="http://en.wikipedia.org/wiki/ISO_8601">ISO 8601</a> standard to follow in order to make our integer dates easier to work with. If we do encode them with the YYYYMMDD format, (thus the 15<sup>th</sup> of January 2011 becomes 20110115), we can easily sort on the column and compare two dates with the standard &gt; and &lt; operators. Additionally, we also escape the ambiguities around date formats in the USA and the rest of the world.</p>
<h5>Attributes</h5>
<p>Building the date key column is a good start but to allow for better analytical capabilities we need to add other attributes. As in most cases we need to analyse our data not only on days, but also on larger intervals (e.g. Months, Quarters and Years), we need to add columns for each of them. A typical requirement is to support both Financial and Calendar date hierarchies. As with dimensions it is ok to have many columns, we can add one for each combination of the type of calendar and period (e.g. FinancialMonth and CalendarMonth, FinancialQuarter and CalendarQuarter, etc.). Other interesting attributes we may want to have materialised in the table are the likes of Weekends, Public Holidays (even though we need to maintain these), Solstice/Equinox and PhaseOfMoon (thanks for<a href="http://blog.kejser.org/"> Thomas Kejser </a>for mentioning these in an online conversation recently). Basically, for a fully functional date table we need to consider anything which could be of business value without going to extremes.</p>
<p>Of course, when working with SSAS we also want to have an integer key for each attribute and possibly a common name for it. This multiplies the number of columns we need by two – one Id and one Name column for each of the attributes we have decided to implement. Some attention needs to be spared when determining the formats of each attribute Id. If we are to be building a hierarchy out of a collection of attributes we want those to form a nice natural hierarchy. That is – each child member should not have two parents with different Ids. To illustrate the concept, let&#8217;s consider two different months – January 2011 and January 2012. While they are the first month of the calendar year, they represent different entities when reporting. We do not aggregate data to January only, but to January in each respective year. Therefore, if we were to write a SQL query to get data for January 2011 and our Ids for both of these members are 1, we would also need to use the Year attribute to get the values we need. Effectively, our hierarchy would have two children with identical Ids of 1 with different parents (with Ids of 2011 and 2012). This is a particular problem when working with SSAS as it definitely prefers unique Ids for each separate attribute member. There is a very easy solution – we can include both the Year and the Month number in the MonthId. In our case, January 2011 gets an Id of 201101 and January 2012 – 201201. Now we don&#8217;t have the same issue. Similarly, we must pay attention when we construct the Ids of other attributes which participate in our hierarchies like Quarter (YYYYQQ) and Half Year (YYYYHH).</p>
<h5>Weeks</h5>
<p>The week is a special case in the calendar. While we can say that Days roll up to Months, which roll up to Quarters, which in turn roll up to Half Years and Years, Weeks are a different story. If we are not using a special calendar like a 4-4-5 calendar, we are dealing with a real-world entity, which does not naturally belong to only one larger period. In most cases we do not have to worry about the week falling between Day and Month as business understands that this is not a very easy to work with hierarchy. However, business users very often are ignorant about the fact that weeks do not roll up nicely to years, too. We can again read ISO 8601, which <a href="http://en.wikipedia.org/wiki/ISO_week_date">also deals </a>with the Week-&gt;Year problem. Basically, the ISO has come up with a simple solution – if we have a week which has dates in two years, we count it towards the year which contains more dates (or, the year which contains the Thursday of the week). Why is this important? Well, we can simply split a week in two, however, this means that certain weeks in our table contain less than 7 days. If we compare such weeks with a Weekly Growth calculation we will notice a problem – the amounts aggregated to them are smaller than usual. Similarly, on a graph showing weekly amounts, we have a dip as the two parts of the same week are plotted as separate points. If the users do not care, then it is not a problem, but it is something we should consider and ask about when building the week attribute in our date table.</p>
<h5>Ranges</h5>
<p>The date table has a limited amount of rows and we have to make a decision on how many are enough. Some developers build date tables with ranges all the way from 1900 to 2100, or even further. As we have <a href="http://en.wikipedia.org/wiki/Leap_year#Gregorian_calendar">roughly 365.25 days per year </a>(note how 1900 is not a leap year, not is 2100 – something Excel doesn&#8217;t know), for 10 years of data we end up with ~3652 rows. With 100 years we have 36525 rows. It is quite doubtful that a data warehouse will contain data for all these years. In most cases it contains a bit of historical data and is designed to keep data for another 20-50 years. To optimise the performance of the queries using the date table it is a good idea to have a dynamic range of dates. In our ETL we can easily keep expanding the range as needed, or collapse it if we ever purge fact data. One thing which is often overlooked when picking the date range is the fact that many times queries depend on the completeness of the date range. A major mistake, which we must avoid are basing the date table on fact data and allowing gaps in the range, and having incomplete top-level periods.</p>
<p>The first problem is easy to explain. Zealously trying to keep the date dimension as small as possible by reducing the number of days (i.e. rows) to only the applicable ones for our fact data can introduce gaps in the overall table. In example, if we have no data for 26<sup>th</sup> of January because our business was closed for<a href="http://en.wikipedia.org/wiki/Australia_Day"> Australia Day</a>, and we &#8220;optimise&#8221; the date table to exclude this day from the date table, all analytics which depend on counting the number of dates in January will be skewed. An average calculation doing Sales/NumberOfDaysPerMonth will divide by 30, not 31. One of the reasons for having a date table at the first place is to avoid such problems. Hence, gaps in the date table must be avoided.</p>
<p>Secondly, we must also ensure that all top-level periods (i.e. Year usually is the top level in the Calendar Hierarchy) must be also complete. It is not acceptable to cut off the date range with a month, so we have a constant number of dates. Even if our fact data is implemented over a fixed window of 24 months (rolling), we should not do the same with the date table. In example, if we are in September 2011 and we have fact data for 24 months prior to this (e.g. September 2009 – September 2011), the date table should also include data for months prior to that (e.g. January 2009 – September 2011). The reason is the same as before – all calculations doing Amount/NumberOfPeriodsWithinAPeriod would be wrong for 2009. Furthermore, if we use something like window functions in SQL partitioning by year and counting the months within the period to compare equivalent ones will be incorrect. The first month of 2009 would be September and the first in 2010 – January. Because of such issues, it is best to keep all top level periods complete. A solution could be removing data from the date table once we are not interested in the complete top level period. In the case of the 24 rolling months, we can remove all of 2009 with all its periods/rows once we move to 2012 and we are interested in January 2010 – January 2012.</p>
<p>In SSAS all date functions like ParallelPeriod and ClosingPeriod work with relative periods. To get the ParallelPeriod for January 2010 in 2009, SSAS will determine that January 2010 is the first month in 2010, go back to 2009 and pick the first month there. If the first month is September 2009, we will get that returned.</p>
<h5>Unknowns</h5>
<p>As with other dimensions, we should also have an Unknown member in the date dimension. While with all other dimensions we usually pick a value like -1 for the Unknown member Id and Name of &#8220;Unknown&#8221;, with a date table things a slightly different as we often have columns which are some sort of a date/time data type and we cannot cast -1 to a date in a meaningful way. Therefore, in many cases we can pick a complete outlier, like 19000101, which we use for storing Unknowns. Depending on the scenario, we may not need to do that, but if we do, there is nothing wrong with doing that as long as we make sure that it is clear that it is a special case. If the data starts in 2001 and we pick 20000101 as an unknown value many users will be wondering why there is some data against that date.</p>
<h5>Conclusion</h5>
<p>The best date table is the one we don&#8217;t notice and take for granted. Given that it is not something that changes at all, the structure of the date table is the one common over many different implementations and whether in SQL Server, SSAS or PowerPivot, the fundamentals stay the same. It can be shared and is part of the base of virtually every BI solution. It, unfortunately, is built wrong very often, thus severely impairing the capability of the system it is a part of. With the arrival of self-service BI I could imagine an increasing need for practical advice on this specific data modelling technique and I hope this article helps with delivering a bit of it.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/bp-msbi?a=Iuob_ngkdBA:km8xoRLI9T4:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/bp-msbi?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/bp-msbi?a=Iuob_ngkdBA:km8xoRLI9T4:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/bp-msbi?i=Iuob_ngkdBA:km8xoRLI9T4:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/bp-msbi?a=Iuob_ngkdBA:km8xoRLI9T4:YwkR-u9nhCs"><img src="http://feeds.feedburner.com/~ff/bp-msbi?d=YwkR-u9nhCs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/bp-msbi/~4/Iuob_ngkdBA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.bp-msbi.com/2011/09/building-a-date-table/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.bp-msbi.com/2011/09/building-a-date-table/</feedburner:origLink></item>
	</channel>
</rss>

