<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	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/"
	>

<channel>
	<title>ixto-Blog &#187; MDX im SQL Server 2005</title>
	<atom:link href="http://www.ixto.de/blog/category/sql-server-2005/mdx-2005/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.ixto.de/blog</link>
	<description>Business Intelligence, Database Consulting, Software Development</description>
	<lastBuildDate>Fri, 03 Sep 2010 11:25:45 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>MDX ParallelPeriod – bleib auf Deinem Level (Andere gibt’s vielleicht nicht)</title>
		<link>http://www.ixto.de/blog/sql-server-2005/mdx-parallelperiod-%e2%80%93-bleib-auf-deinem-level-andere-gibt%e2%80%99s-vielleicht-nicht/</link>
		<comments>http://www.ixto.de/blog/sql-server-2005/mdx-parallelperiod-%e2%80%93-bleib-auf-deinem-level-andere-gibt%e2%80%99s-vielleicht-nicht/#comments</comments>
		<pubDate>Mon, 12 Oct 2009 14:05:31 +0000</pubDate>
		<dc:creator>Marcel Ebner</dc:creator>
				<category><![CDATA[MDX im SQL Server 2005]]></category>
		<category><![CDATA[MDX im SQL Server 2008]]></category>
		<category><![CDATA[SQL Server 2005]]></category>
		<category><![CDATA[SQL Server 2008]]></category>

		<guid isPermaLink="false">http://www.ixto.de/blog/allgemein/mdx-parallelperiod-%e2%80%93-bleib-auf-deinem-level-andere-gibt%e2%80%99s-vielleicht-nicht/</guid>
		<description><![CDATA[Um innerhalb einer Zeitdimension zurückliegende Member zu erreichen braucht es kein Voodoo, MDX stellt eine bequeme Funktion namens &#8220;PARALLELPERIOD&#8221; zur Verfügung, welche zu einem angegebenen Element (Bsp. August 2003) über eine Ebene der Zeitdimension (Monat, Quartal, Jahr …) eine bestimmte Anzahl von Schritten (12 Monate, 2 Jahre o. ä.) zurück oder vorwärts geht.
Zum Beispiel folgende [...]]]></description>
			<content:encoded><![CDATA[<p>Um innerhalb einer Zeitdimension zurückliegende Member zu erreichen braucht es kein Voodoo, MDX stellt eine bequeme Funktion namens &#8220;PARALLELPERIOD&#8221; zur Verfügung, welche zu einem angegebenen Element (Bsp. August 2003) über eine Ebene der Zeitdimension (Monat, Quartal, Jahr …) eine bestimmte Anzahl von Schritten (12 Monate, 2 Jahre o. ä.) zurück oder vorwärts geht.</p>
<p>Zum Beispiel folgende Abfrage:</p>
<p style="margin-left: 35pt"> <span style="color: blue; font-family: Courier New; font-size: 10pt">WITH</span><br />
<span style="font-family: Courier New; font-size: 10pt"><span style="color: blue">MEMBER</span> LevelMonth_OneYearAgo <span style="color: blue">AS</span></span><br />
<span style="font-family: Courier New; font-size: 10pt"><span style="color: maroon">PARALLELPERIOD</span>([Date].[Calendar].[Month],12,</span><br />
<span style="font-family: Courier New; font-size: 10pt">[Date].[Calendar].<span style="color: maroon">CURRENTMEMBER</span>).<span style="color: blue">MEMBER_CAPTION</span></span><br />
<span style="font-family: Courier New; font-size: 10pt"><span style="color: blue">MEMBER</span> LevelYear_OneYearAgo <span style="color: blue">AS</span></span><br />
<span style="font-family: Courier New; font-size: 10pt"><span style="color: maroon">PARALLELPERIOD</span>([Date].[Calendar].[Calendar Year],1,</span><br />
<span style="font-family: Courier New; font-size: 10pt">[Date].[Calendar].<span style="color: maroon">CURRENTMEMBER</span>).<span style="color: blue">MEMBER_CAPTION</span></span><br />
<span style="font-family: Courier New; font-size: 10pt"><span style="color: blue">SELECT</span> {</span><br />
<span style="font-family: Courier New; font-size: 10pt"> LevelMonth_OneYearAgo</span><br />
<span style="font-family: Courier New; font-size: 10pt"> ,LevelYear_OneYearAgo</span><br />
<span style="font-family: Courier New; font-size: 10pt">} <span style="color: blue">ON</span> 0 ,</span><br />
<span style="font-family: Courier New; font-size: 10pt">{</span><br />
<span style="font-family: Courier New; font-size: 10pt">[Date].[Calendar].[Month].&amp;[2003]&amp;[8]</span><br />
<span style="font-family: Courier New; font-size: 10pt">}<span style="color: blue">ON</span> 1 <span style="color: blue">FROM</span> [Adventure Works]</span></p>
<p>liefert zurück:</p>
<p><img src="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/101209_0001_Parallel1.png" /></p>
<p>Obwohl das Hierarchielevel &#8220;[Date].[Calendar].[Calendar Year]&#8221; auf keiner Achse angegeben ist, kann es durch seine bestehende Attributrelation zur Ebene &#8220;[Date].[Calendar].[Month]&#8221; angesprochen werden .</p>
<p>Sind also Attributbeziehungen innerhalb der verschiedenen Zeitebenen definiert, können auch andere als in der Abfrage verwendete Ebenen der Zeitdimension mit PARALLELPERIOD verwendet werden.</p>
<p>Was aber passiert, wenn es im angegebenen zurückliegenden Zeitraum keinen Member  gibt? Im AdventureWorks Cube 2008 ist der erste Member der Zeitdimension der erste Juli 2001. Ersetzt man den oben abgefragten Monat auf der Achse mit &#8220;[Date].[Calendar].[Month].&amp;[2002]&amp;[6]&#8221; liefert die Abfrage folgendes zurück:</p>
<p><img src="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/101209_0001_Parallel2.png" /></p>
<p>Das Ergebnis für PARALLELPERIOD mit Level &#8220;Month&#8221; ist korrekt, aber was ist mit dem Ergebnis für Level &#8220;Year&#8221; los? Angezeigt wird der Dezember 2001, der nun definitiv kein Jahr hinter dem Juni 2002 liegt. In diesem Fall wird nun der letzte Monat des Vorjahres angezeigt, also das letzte Member der darunterliegenden Ebene. Auch darauf sollte man sich nun nicht verlassen, beachten Sie das folgende Beispiel (und, wenn möglich, führen Sie das Statement auch mal auf Ihrem eigenen Adventure Works Cube aus)</p>
<p>Ziel der Abfrage ist den allseits beliebten &#8220;Sales Amount&#8221; der Monate 2001 bis Ende 2002 zu ermitteln. Beim Cubebrowsen stellt sich folgendes heraus:</p>
<p><img src="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/101209_0001_Parallel3.png" /></p>
<p>Zwischen Januar 2001 und Juni 2001 sind keine Werte für &#8220;Sales Amount&#8221; vorhanden, eine ähnliche MDX-Abfrage wie folgende:</p>
<p style="margin-left: 35pt"> <span style="color: blue; font-family: Courier New; font-size: 10pt">WITH</span><span style="color: green; font-family: Courier New; font-size: 10pt"></span><br />
<span style="color: green; font-family: Courier New; font-size: 10pt">//LAG: </span><br />
<span style="color: green; font-family: Courier New; font-size: 10pt">Gibt das Element zurück, das eine angegebene Anzahl von Positionen (hier 12) vor einem angegebenen Element entlang der Dimension des Elements liegt.</span><br />
<span style="font-family: Courier New; font-size: 10pt"><span style="color: blue">MEMBER</span> [Measures].[Lag_Month] <span style="color: blue">AS</span></span><br />
<span style="font-family: Courier New; font-size: 10pt">([Measures].[Sales Amount],</span><br />
<span style="font-family: Courier New; font-size: 10pt">[Date].[Calendar].<span style="color: maroon">CURRENTMEMBER</span>.<span style="color: blue">LAG</span>(12))</span><br />
<span style="color: green; font-family: Courier New; font-size: 10pt"><br />
//PARALLELPERIOD: Gibt ein Element aus einer früheren Periode in derselben relativen Position wie ein angegebenes Element zurück</span><br />
<span style="font-family: Courier New; font-size: 10pt"><span style="color: blue">MEMBER</span> [Measures].[PP_LevelMonth] <span style="color: blue">AS</span></span><br />
<span style="font-family: Courier New; font-size: 10pt">([Measures].[Sales Amount],</span><br />
<span style="font-family: Courier New; font-size: 10pt"><span style="color: maroon">PARALLELPERIOD</span>([Date].[Calendar].[Month],12,</span><br />
<span style="font-family: Courier New; font-size: 10pt">[Date].[Calendar].<span style="color: maroon">CURRENTMEMBER</span>))</span><br />
<span style="font-family: Courier New; font-size: 10pt"><span style="color: blue"><br />
MEMBER</span> [Measures].[PP_LevelYear] <span style="color: blue">AS</span></span><br />
<span style="font-family: Courier New; font-size: 10pt">([Measures].[Sales Amount],</span><br />
<span style="font-family: Courier New; font-size: 10pt"><span style="color: maroon">PARALLELPERIOD</span>([Date].[Calendar].[Calendar Year],1,</span><br />
<span style="font-family: Courier New; font-size: 10pt">[Date].[Calendar].<span style="color: maroon">CURRENTMEMBER</span>))</span><br />
<span style="font-family: Courier New; font-size: 10pt"><span style="color: blue"><br />
SELECT</span> {</span><br />
<span style="font-family: Courier New; font-size: 10pt"> [Measures].[Sales Amount]</span><br />
<span style="font-family: Courier New; font-size: 10pt">,[Measures].[Lag_Month]</span><br />
<span style="font-family: Courier New; font-size: 10pt">,[Measures].[PP_LevelMonth]</span><br />
<span style="font-family: Courier New; font-size: 10pt">,[Measures].[PP_LevelYear]</span><br />
<span style="font-family: Courier New; font-size: 10pt">} <span style="color: blue">ON</span> 0,</span><br />
<span style="font-family: Courier New; font-size: 10pt">{ <span style="color: green">//Level month on axis 1</span></span><br />
<span style="font-family: Courier New; font-size: 10pt">[Date].[Calendar].[Month].&amp;[2001]&amp;[7]</span><br />
<span style="font-family: Courier New; font-size: 10pt">    : [Date].[Calendar].[Month].&amp;[2002]&amp;[12]</span><br />
<span style="font-family: Courier New; font-size: 10pt">} <span style="color: blue">ON</span> 1 <span style="color: blue">FROM</span> [Adventure Works]</span></p>
<p>ergibt:</p>
<p><img src="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/101209_0001_Parallel4.png" /></p>
<p>Die &#8220;Sales Amount&#8221; Werte für das mit PARALLELPERIOD  Level &#8220;Year&#8221; erstellte Member sind in Unordnung geraten.  Schon ab Januar 2002 werden die rückliegenden Werte angezeigt, obwohl erst der Juli 2002 Werte für das aktuelle und das zurückliegende Jahr aufweist.</p>
<p>Die Werte der Member welche mit der MDX Funktion &#8220;Lag&#8221; oder mit dem in der Achse verwendeten Level, nämlich &#8220;Month&#8221; erstellt wurden sind korrekt.</p>
<p>Deshalb, &#8220;Schuster &#8211; bleib bei Deinem Leisten&#8221; und bei PARALLELPERIOD im abgefragten Level.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ixto.de/blog/sql-server-2005/mdx-parallelperiod-%e2%80%93-bleib-auf-deinem-level-andere-gibt%e2%80%99s-vielleicht-nicht/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Problem mit Excel 2007 und Analysis Services KPIs</title>
		<link>http://www.ixto.de/blog/sql-server-2008/problem-mit-excel-2007-und-analysis-services-kpis/</link>
		<comments>http://www.ixto.de/blog/sql-server-2008/problem-mit-excel-2007-und-analysis-services-kpis/#comments</comments>
		<pubDate>Wed, 15 Jul 2009 09:33:09 +0000</pubDate>
		<dc:creator>Markus Raatz</dc:creator>
				<category><![CDATA[MDX im SQL Server 2005]]></category>
		<category><![CDATA[SQL Server 2008]]></category>

		<guid isPermaLink="false">http://www.ixto.de/blog/allgemein/problem-mit-excel-2007-und-analysis-services-kpis/</guid>
		<description><![CDATA[Das Einbinden und Anzeigen von Analysis Services KPIs in Excel 2007 ist ja eine faszinierende und oft beworbene Möglichkeit. Leider zeigt sich in der Praxis oft, dass KPIs wirklich noch einmal speziell für Excel 2007 geprüft werden müssen, weil Berechnungen und Formatierungen in dem MDX, das Excel bei Abfragen generiert, oftmals nicht funktionieren. Dasselbe gilt [...]]]></description>
			<content:encoded><![CDATA[<p><span style="font-family:Arial; font-size:10pt">Das Einbinden und Anzeigen von Analysis Services KPIs in Excel 2007 ist ja eine faszinierende und oft beworbene Möglichkeit. Leider zeigt sich in der Praxis oft, dass KPIs wirklich noch einmal speziell für Excel 2007 geprüft werden müssen, weil Berechnungen und Formatierungen in dem MDX, das Excel bei Abfragen generiert, oftmals nicht funktionieren. Dasselbe gilt leider auch für KPIs, die in einer SharePoint-KPI-Liste verwendet werden sollen. Unlängst ist uns aber ein besonders gemeiner Fall begegnet: beim Öffnen einer Excel-Tabelle mit enthaltener Cube-Abfrage erschien immer dieser Fehler:<br />
</span></p>
<p>
 </p>
<p><img src="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/071509_0933_ProblemmitE1.jpg" alt=""/><span style="font-family:Arial; font-size:10pt"><br />
		</span></p>
<p>
 </p>
<p><span style="color:black; font-family:Arial; font-size:10pt">Der Grund war ein auf dem Cube definierter KPI mit einer Gewichtung:<br />
</span></p>
<p>
 </p>
<p><img src="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/071509_0933_ProblemmitE2.jpg" alt=""/><span style="color:black; font-family:Arial; font-size:10pt"><br />
		</span></p>
<p>
 </p>
<p><span style="color:black; font-family:Arial; font-size:10pt">Nachdem die Gewichtung entfernt wurde, ließen sich die Excel-Tabellen wieder normal öffnen. Vielen Dank an Horst Haschke von Hiestand und Suhr für das Übermitteln der Lösung!<br />
</span></p>
]]></content:encoded>
			<wfw:commentRss>http://www.ixto.de/blog/sql-server-2008/problem-mit-excel-2007-und-analysis-services-kpis/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>OLAP-Datenquellen webbasiert abfragen mit  Dundas OLAP-Browser</title>
		<link>http://www.ixto.de/blog/allgemein/olap-datenquellen-webbasiert-abfragen-mit-dundas-olap-browser/</link>
		<comments>http://www.ixto.de/blog/allgemein/olap-datenquellen-webbasiert-abfragen-mit-dundas-olap-browser/#comments</comments>
		<pubDate>Mon, 13 Apr 2009 15:47:57 +0000</pubDate>
		<dc:creator>Martin Ihrke</dc:creator>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[MDX im SQL Server 2005]]></category>
		<category><![CDATA[MDX im SQL Server 2008]]></category>
		<category><![CDATA[Dundas]]></category>
		<category><![CDATA[Olap]]></category>

		<guid isPermaLink="false">http://www.ixto.de/blog/allgemein/olap-datenquellen-webbasiert-abfragen-mit-dundas-olap-browser/</guid>
		<description><![CDATA[Zahreiche ixto-Kunden wünschen sich, und damit sind sie wahrscheinlich nicht alleine, denn ihr Wunsch ist verständlich, eine Möglichkeit, OLAP-Datenquellen Web-basiert abzufragen. Die Vorteile liegen auf der Hand: das Vermeiden einer lokalen Softwareinstallation und deren Pflege sowie der damit verbunden Flexibilität. Der Markt an solchen Tools ist recht überschaubar und es findet sich sogar ein alter [...]]]></description>
			<content:encoded><![CDATA[<p>Zahreiche ixto-Kunden wünschen sich, und damit sind sie wahrscheinlich nicht alleine, denn ihr Wunsch ist verständlich, eine Möglichkeit, OLAP-Datenquellen Web-basiert abzufragen. Die Vorteile liegen auf der Hand: das Vermeiden einer lokalen Softwareinstallation und deren Pflege sowie der damit verbunden Flexibilität. Der Markt an solchen Tools ist recht überschaubar und es findet sich sogar ein alter Bekannter in der Schar der Anbietern: Dundas Data Visualization. Bekannt vor allem durch seine Chart-Elemente für Reporting Services, die bekanntlich seit SQL Server 2008 auch in diesem integriert sind, liefert Dundas ebenfalls einen OLAP-Client für Web-basierte Anwendungen. Die Funktionalität und Tauglichkeit des solchen soll an dieser Stelle vorgestellt werden.</p>
<p>Zunächst ist zu bemerken, dass der Dundas Olap-Browser als Version für Windows Forms als auch für ASP.Net verfügbar ist. Da eingangs die Rede eines reinen Webclients ist, ist die Entscheidung leicht zu treffen und fällt selbstverständlich auf ASP.Net. Wie bei Dundas üblich, gibt es eine Testversion, die weder in Funktionalität noch in zeitlicher Lauffähigkeit beschränkt ist, sondern nur ein Wasserzeichen in sämtlichen Grafiken trägt, um als Demo aufzufallen. Die ist nach einer Registrierung bei Dundas schnell installiert und bringt auch gleich zahlreiche Beispiel-Anwendungen mit, die die Funktionalitäten hinreichend demonstrieren. Sie sind sind sofort einsatzbereit, da ein Offline-Cube ebenfalls zum Lieferumfang gehört, falls keine OLAP-Datenquelle zur Verfügung steht. Eigene Analysis-Services Datenbanken sind aber auch schnell angebunden, so dass wir unverzüglich in unseren Cubes browsen können.</p>
<p>Dem Entwickler stehen dazu zwei Wege offen:</p>
<ul>
<li>Zum einen gibt es eine fertige Olap-Browser Komponte in der VisualStudio Toolbox, der direkt in eine ASP.NET-Seite eingefügt werden kann und auf den Namen <em>OlapClient</em> hört. Er enthält bereits alle wesentlichen Funktionen, so dass der Aufwand für Anpassungen des Layouts und der Funktionalität gegen null geht.</li>
<li>Darüber hinaus sind die einzelnen Bestandteile als Einzelkomponenten verfügbar, die sich frei positionieren und kombinieren lassen. Diese sind im Detail:
<ul>
<li>- OlapChart,</li>
<li>- OlapGrid,</li>
<li>- CubeSelector,</li>
<li>- CubeDimensionBrowser</li>
</ul>
<p>und einige mehr. Bindeglied der einzelnen Komponenten ist das OlapManager-Element. Über dieses wird definiert, dass die Komponenten auf die gleichen Daten zugreifen, Kennzahlen und Dimensionen verknüpft werden und Filter korrekt wirken.</li>
</ul>
<p> <img border="0" src="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/033009_1546_OLAPDatenqu1.jpg" align="textTop" height="301" width="176" /></p>
<p>Der OLAP-Browser organisiert sich in sogenannten Reports, die beliebig angelegt und verändert werden können. Einmal definierte Abfragen auf die Cubes bleiben damit verfüg- und veränderbar.</p>
<p>Visualisieren lassen sich die Daten innerhalb von Grafiken (Charts) und Pivottabellen (Grids). Dazu stehen die üblichen gestalterischen Möglichkeiten der Farb- und Formenwahl zur Verfügung. Drilldown, Drillthrough und weitere Cube-Operationen sind ebenfalls genauso verfügbar wie Tabellen-Operationen wie das Transponieren.</p>
<p><img border="0" src="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/033009_1546_OLAPDatenqu2.jpg" height="345" width="481" /></p>
<p>Ein Highlight ist ohne Zweifel die Web2.0-Funktionalität basierend auf dem Duo JavaScript und XML. Measures, Dimensionen und Filter lassen sich durch Drag&amp;Drop wie bei einer lokalen Anwendung definieren, wobei sich das Look&amp;Feel an den einschlägigen OLAP-Werkzeugen, wie dem SQL Server Management Studio orientiert.</p>
<p>Etwas hakelig, wenn auch trotzdem möglich, ist der Export nach Microsoft Excel. Es handelt sich hier um ein oft durch Kunden angefragtes Feature, leider ist es trotzdem keine integrierte Funktion des OLAP-Browsers. Jedoch liefern die Beispieldateien hier genügend Informationen in Form von Beispiel-Code, um den Export auch in eigene Anwendungen einzubauen.</p>
<p><img border="0" src="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/033009_1546_OLAPDatenqu3.jpg" height="410" width="591" /></p>
<p>Am Ende bleibt trotz dieser kleinen Einschränkung ein sehr positiver Eindruck eines stabilen und einfach zu handhabenden Werkzeugs, OLAP-Quellen auch ohne lokal installierte Software abzufragen.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ixto.de/blog/allgemein/olap-datenquellen-webbasiert-abfragen-mit-dundas-olap-browser/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Korrekte MDX-Berechnungen mit den Analysis Services trotz Multiselect</title>
		<link>http://www.ixto.de/blog/sql-server-2005/mdx-2005/korrekte-mdx-berechnungen-mit-den-analysis-services-trotz-multiselect/</link>
		<comments>http://www.ixto.de/blog/sql-server-2005/mdx-2005/korrekte-mdx-berechnungen-mit-den-analysis-services-trotz-multiselect/#comments</comments>
		<pubDate>Mon, 05 Jan 2009 09:08:36 +0000</pubDate>
		<dc:creator>Markus Schechner</dc:creator>
				<category><![CDATA[MDX im SQL Server 2005]]></category>

		<guid isPermaLink="false">http://www.ixto.de/blog/sql-server-2005/mdx/korrekte-mdx-berechnungen-mit-den-analysis-services-trotz-multiselect/</guid>
		<description><![CDATA[Seit mehreren Jahren wird immer wieder &#252;ber die Problematik von berechneten Elementen in den Analysis Services in Verbindung mit Multiselects diskutiert. 
&#160;
So schrieb Mosha bereits 2005 in Writing multiselect friendly MDX calculations &#252;ber die Probleme, die auftreten wenn eine Berechnung ein CURRENTMEMBER ben&#246;tigt und Sets in der WHERE Clause verwendet werden. 
&#160;
Das Thema ist aber [...]]]></description>
			<content:encoded><![CDATA[<p>Seit mehreren Jahren wird immer wieder &#252;ber die Problematik von berechneten Elementen in den Analysis Services in Verbindung mit Multiselects diskutiert. </p>
<p>&#160;</p>
<p>So schrieb Mosha bereits 2005 in <a href="http://sqlblog.com/blogs/mosha/archive/2005/11/18/writing-multiselect-friendly-mdx-calculations.aspx" target="_blank">Writing multiselect friendly MDX calculations</a> &#252;ber die Probleme, die auftreten wenn eine Berechnung ein CURRENTMEMBER ben&#246;tigt und Sets in der WHERE Clause verwendet werden. </p>
<p>&#160;</p>
<p>Das Thema ist aber leider immer noch aktuell und wurde durch Excel 2007 und dessen Vorliebe f&#252;r Subselects beim Ausw&#228;hlen mehrerer Elemente der gleichen Hierarchie eher noch verschlimmert. Denn dann geben die Analysis Services unter Umst&#228;nden keinen Fehler mehr zur&#252;ck, sondern zeigen einfach falsche Werte an.</p>
<p>&#160;</p>
<p>Da die Hoffnung &#8222;Mit Katmai wird alles besser&#8220; f&#252;r diese Problematik auch nicht zutrifft, wird im Folgenden noch mal auf die Problematik eingegangen und anschlie&#223;end mit Hilfe von SCOPE eine m&#246;gliche L&#246;sung erkl&#228;rt. Die Beispiele basieren wie immer auf dem Adventure Works Cube, den es bei <a href="http://www.codeplex.com/MSFTDBProdSamples" target="_blank">Codeplex</a> zum Download gibt.</p>
<p>&#160;</p>
<p><b><u>Das Problem</u></b></p>
<p>Um das eigentliche Problem zu verstehen, ben&#246;tigen wir zwei berechnete Elemente. Zum einen werden wir uns &#8222;Ratio to Parent Product&#8220; anschauen, das bereits in der Adventure Works enthalten ist und folgende Definition hat:</p>
<p>&#160;</p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal; mso-pagination: none; mso-layout-grid-align: none"><span lang="EN-US" style="font-size: 10pt; color: blue; font-family: &#39;Courier New&#39;; mso-ansi-language: en-us">Create</span><span lang="EN-US" style="font-size: 10pt; font-family: &#39;Courier New&#39;; mso-ansi-language: en-us"> <span style="color: blue">Member</span> <span style="color: blue">CurrentCube</span>.[Measures].[Ratio to Parent Product] </span>
</p>
</p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal; mso-pagination: none; mso-layout-grid-align: none"><span lang="EN-US" style="font-size: 10pt; font-family: &#39;Courier New&#39;; mso-ansi-language: en-us"></span>
<p>&#160;</p>
<p>   <span lang="EN-US" style="font-size: 10pt; font-family: &#39;Courier New&#39;; mso-ansi-language: en-us"><span style="mso-spacerun: yes">&#160;</span><span style="color: blue">As</span> <span style="color: blue">Case </span>
</p>
<p>   </span></p>
</p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal; mso-pagination: none; mso-layout-grid-align: none"><span lang="EN-US" style="font-size: 10pt; color: blue; font-family: &#39;Courier New&#39;; mso-ansi-language: en-us"></span>
<p>&#160;</p>
<p>   <span lang="EN-US" style="font-size: 10pt; font-family: &#39;Courier New&#39;; mso-ansi-language: en-us"><span style="mso-spacerun: yes">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: blue">When</span> [Product].[Product Model Categories].<span style="color: maroon">CurrentMember</span>.<span style="color: blue">Level</span>.<span style="color: maroon">Ordinal</span> </span>
</p>
</p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal; mso-pagination: none; mso-layout-grid-align: none"><span lang="EN-US" style="font-size: 10pt; font-family: &#39;Courier New&#39;; mso-ansi-language: en-us"><span style="mso-spacerun: yes">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span>= 0 </span>
</p>
</p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal; mso-pagination: none; mso-layout-grid-align: none"><span lang="EN-US" style="font-size: 10pt; font-family: &#39;Courier New&#39;; mso-ansi-language: en-us"><span style="mso-spacerun: yes">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: blue">Then</span> 1 </span>
</p>
</p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal; mso-pagination: none; mso-layout-grid-align: none"><span lang="EN-US" style="font-size: 10pt; font-family: &#39;Courier New&#39;; mso-ansi-language: en-us"></span>
<p>&#160;</p>
<p>   <span lang="EN-US" style="font-size: 10pt; font-family: &#39;Courier New&#39;; mso-ansi-language: en-us"><span style="mso-spacerun: yes">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: blue">Else</span> [Measures].[Sales Amount] </span>
</p>
</p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal; mso-pagination: none; mso-layout-grid-align: none"><span lang="EN-US" style="font-size: 10pt; font-family: &#39;Courier New&#39;; mso-ansi-language: en-us"><span style="mso-spacerun: yes">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span>/ </span>
</p>
</p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal; mso-pagination: none; mso-layout-grid-align: none"><span lang="EN-US" style="font-size: 10pt; font-family: &#39;Courier New&#39;; mso-ansi-language: en-us"><span style="mso-spacerun: yes">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span>( [Product].[Product Model Categories].<span style="color: maroon">CurrentMember</span>.<span style="color: maroon">Parent</span>, </span>
</p>
</p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal; mso-pagination: none; mso-layout-grid-align: none"><span lang="EN-US" style="font-size: 10pt; font-family: &#39;Courier New&#39;; mso-ansi-language: en-us"><span style="mso-spacerun: yes">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span>[Measures].[Sales Amount] ) </span>
</p>
</p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal; mso-pagination: none; mso-layout-grid-align: none"><span lang="EN-US" style="font-size: 10pt; font-family: &#39;Courier New&#39;; mso-ansi-language: en-us"></span>
<p>&#160;</p>
<p>   <span lang="EN-US" style="font-size: 10pt; font-family: &#39;Courier New&#39;; mso-ansi-language: en-us"><span style="mso-spacerun: yes">&#160;&#160;&#160; </span><span style="color: blue">End</span>, </span>
</p>
</p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal; mso-pagination: none; mso-layout-grid-align: none"><span style="font-size: 10pt; color: blue; line-height: 115%; font-family: &#39;Courier New&#39;">Format_String</span><span style="font-size: 10pt; line-height: 115%; font-family: &#39;Courier New&#39;"> = <span style="color: #a31515">&quot;Percent&quot;</span> ;</span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal; mso-pagination: none; mso-layout-grid-align: none"><span style="font-size: 10pt; line-height: 115%; font-family: &#39;Courier New&#39;"></span></p>
<p>Zus&#228;tzlich definieren wir uns ein einfaches eigenes Measure, dass die Anzahl der Produkte f&#252;r die jeweilige Auswahl anzeigt:</p>
<p>&#160;</p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal; mso-pagination: none; mso-layout-grid-align: none"><span lang="EN-US" style="font-size: 10pt; color: blue; font-family: &#39;Courier New&#39;; mso-ansi-language: en-us">Create</span><span lang="EN-US" style="font-size: 10pt; font-family: &#39;Courier New&#39;; mso-ansi-language: en-us"> <span style="color: blue">MEMBER</span> <span style="color: blue">CurrentCube</span>.[Measures].[Number of Products] </span>
</p>
</p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal; mso-pagination: none; mso-layout-grid-align: none"><span lang="EN-US" style="font-size: 10pt; color: blue; font-family: &#39;Courier New&#39;; mso-ansi-language: en-us">AS </span>
</p>
</p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal; mso-pagination: none; mso-layout-grid-align: none"><span lang="EN-US" style="font-size: 10pt; font-family: &#39;Courier New&#39;; mso-ansi-language: en-us"><span style="mso-spacerun: yes">&#160;&#160;&#160; </span><span style="color: blue">COUNT</span>(<span style="color: blue">EXISTING</span>([Product].[Product].[Product].<span style="color: blue">MEMBERS</span>)); </span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal; mso-pagination: none; mso-layout-grid-align: none"><span lang="EN-US" style="font-size: 10pt; font-family: &#39;Courier New&#39;; mso-ansi-language: en-us"></span>
</p>
</p>
<p>EXISTING sorgt dabei daf&#252;r, dass nicht immer die gleiche Anzahl zur&#252;ckgegeben wird, sondern das Measure f&#252;r die jeweils ausgew&#228;hlten Koordinaten des Cubes neu berechnet wird.</p>
<p>&#160;</p>
<p>Nun k&#246;nnen wir uns das ganze in Excel ansehen. Wenn wir die beiden berechneten Measures und zus&#228;tzlich noch den Sales Amount ausw&#228;hlen und die &#8222;Product Categories&#8220; auf den Zeilen ausgeben, dann ergibt sich folgendes Bild: </p>
<p>&#160;</p>
<p><a href="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/KorrekteMDXBerechnungenmitdenAnalysisSer_87F6/clip_image002.jpg"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="145" alt="clip_image002" src="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/KorrekteMDXBerechnungenmitdenAnalysisSer_87F6/clip_image002_thumb.jpg" width="519" border="0" /></a></p>
<p>&#160;</p>
<p>Wie zu erwarten war, werden sowohl Number of Products, als auch die Ratio to Parent richtig f&#252;r die einzelnen Produktkategorien angezeigt. Dass die Summe der Einzelwerte der &#8222;Number of Products&#8220; nicht dem Gesamtergebnis entspricht, liegt &#252;brigens daran, dass 209 Produkte dem, ungl&#252;cklicherweise unsichtbaren, UnknownMember zugeschlagen wurden.</p>
<p>&#160;</p>
<p>Wenn wir nun die Produktkategorien von den Zeilen in den Filter verschieben und dort mehrere Elemente ausw&#228;hlen,</p>
<p>&#160;</p>
<p><a href="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/KorrekteMDXBerechnungenmitdenAnalysisSer_87F6/clip_image004.jpg"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="251" alt="clip_image004" src="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/KorrekteMDXBerechnungenmitdenAnalysisSer_87F6/clip_image004_thumb.jpg" width="211" border="0" /></a></p>
<p>&#160;</p>
<p>dann nutzt Excel im Hintergrund ein SUBSELECT, um diese Einschr&#228;nkung abzubilden. Das Ergebnis sieht dann folgenderma&#223;en aus:</p>
<p>&#160;</p>
<p><a href="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/KorrekteMDXBerechnungenmitdenAnalysisSer_87F6/clip_image006.jpg"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="106" alt="clip_image006" src="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/KorrekteMDXBerechnungenmitdenAnalysisSer_87F6/clip_image006_thumb.jpg" width="390" border="0" /></a></p>
<p>&#160;</p>
<p>F&#252;r den Sales Amount wird korrekt die Summe der Kategorien &#8222;Accessoires&#8220; und &#8222;Bikes&#8220; angezeigt, was beweist, dass Excel mit seinem MDX nicht v&#246;llig daneben liegen kann. Trotzdem stimmen die Zahlen der anderen beiden Measures nicht. Es sieht aus, als w&#228;re gar keine Einschr&#228;nkung gemacht worden. W&#252;rde man sich ein Measure definieren, das <span style="font-size: 10pt; line-height: 115%; font-family: &#39;Courier New&#39;; mso-ansi-language: de; mso-fareast-font-family: calibri; mso-fareast-theme-font: minor-latin; mso-fareast-language: en-us; mso-bidi-language: ar-sa">[Product].[Product Model Categories].<span style="color: maroon">CurrentMember</span>.Name</span> ausgibt, dann k&#246;nnte man sehen, dass genau das geschehen ist. Innerhalb der MDX-Scripts, gibt es nur eine gew&#228;hlte Produktkategorie, n&#228;mlich &#8222;[All]&#8220;. Unsere berechneten Elemente bekommen von der Tatsache, dass sie in einem beschr&#228;nkten Subcube laufen, nichts mit.</p>
<p>&#160;</p>
<p><b><u>Die L&#246;sung?</u></b></p>
<p>Die Grundidee, um dieses Problem zu umgehen, ist echte Measures anzulegen und diese dann per SCOPE so zu &#252;berschreiben, dass die eigentlichen Werte dann wieder per MDX ermittelt werden. </p>
<p>&#160;</p>
<p>Beginnen wir also mit dem Anlegen eines &#8222;echten&#8220; Measures f&#252;r die Anzahl der Produkte. Da es diesen Wert auf Faktenebene nicht gibt, m&#252;ssen wir uns also erst mal eine Spalte erzeugen, die wir sp&#228;ter als Quelle f&#252;r unser neues Measure nutzen k&#246;nnen. Wir erzeugen uns also in der Data Source View f&#252;r die FactSalesSummary eine leere Dummy-Spalte.</p>
<p>&#160;</p>
<p><a href="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/KorrekteMDXBerechnungenmitdenAnalysisSer_87F6/clip_image008.jpg"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="397" alt="clip_image008" src="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/KorrekteMDXBerechnungenmitdenAnalysisSer_87F6/clip_image008_thumb.jpg" width="414" border="0" /></a></p>
<p>&#160;</p>
<p>Dazu &#252;berarbeiten wir die Abfrage, die hinter der Faktentabelle liegt so, dass in beiden Teilen des UNIONS die neue Spalte &#8222;Dummy&#8220; auftaucht. </p>
<p>&#160;</p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal; mso-pagination: none; mso-layout-grid-align: none"><span lang="EN-US" style="font-size: 10pt; color: blue; font-family: &#39;Courier New&#39;; mso-ansi-language: en-us">SELECT</span><span lang="EN-US" style="font-size: 10pt; font-family: &#39;Courier New&#39;; mso-ansi-language: en-us"><span style="mso-spacerun: yes">&#160;&#160;&#160;&#160; </span></span>
</p>
</p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal; mso-pagination: none; mso-layout-grid-align: none"><span lang="EN-US" style="font-size: 10pt; font-family: &#39;Courier New&#39;; mso-ansi-language: en-us"><span style="mso-tab-count: 1">&#160;&#160;&#160;&#160;&#160; </span>&#8230; </span>
</p>
</p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal; mso-pagination: none; mso-layout-grid-align: none"><span lang="EN-US" style="font-size: 10pt; font-family: &#39;Courier New&#39;; mso-ansi-language: en-us"><span style="mso-tab-count: 1">&#160;&#160;&#160;&#160;&#160; </span><span style="color: gray">,</span> <span style="color: gray">NULL</span> <span style="color: blue">AS</span> [Dummy] </span>
</p>
</p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal; mso-pagination: none; mso-layout-grid-align: none"><span lang="EN-US" style="font-size: 10pt; color: blue; font-family: &#39;Courier New&#39;; mso-ansi-language: en-us">FROM</span><span lang="EN-US" style="font-size: 10pt; font-family: &#39;Courier New&#39;; mso-ansi-language: en-us"> FactResellerSales </span>
</p>
</p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal; mso-pagination: none; mso-layout-grid-align: none"><span lang="EN-US" style="font-size: 10pt; color: blue; font-family: &#39;Courier New&#39;; mso-ansi-language: en-us">UNION </span>
</p>
</p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal; mso-pagination: none; mso-layout-grid-align: none"><span lang="EN-US" style="font-size: 10pt; color: blue; font-family: &#39;Courier New&#39;; mso-ansi-language: en-us">SELECT</span><span lang="EN-US" style="font-size: 10pt; font-family: &#39;Courier New&#39;; mso-ansi-language: en-us"><span style="mso-spacerun: yes">&#160;&#160;&#160;&#160; </span></span>
</p>
</p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal; mso-pagination: none; mso-layout-grid-align: none"><span lang="EN-US" style="font-size: 10pt; font-family: &#39;Courier New&#39;; mso-ansi-language: en-us"><span style="mso-tab-count: 1">&#160;&#160;&#160;&#160;&#160; </span>&#8230; </span>
</p>
</p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal; mso-pagination: none; mso-layout-grid-align: none"><span lang="EN-US" style="font-size: 10pt; font-family: &#39;Courier New&#39;; mso-ansi-language: en-us"><span style="mso-tab-count: 1">&#160;&#160;&#160;&#160;&#160; </span><span style="color: gray">,</span> <span style="color: gray">NULL</span> <span style="color: blue">AS</span> [Dummy] </span>
</p>
</p>
<p><span style="font-size: 10pt; color: blue; line-height: 115%; font-family: &#39;Courier New&#39;; mso-ansi-language: de; mso-fareast-font-family: calibri; mso-fareast-theme-font: minor-latin; mso-fareast-language: en-us; mso-bidi-language: ar-sa">FROM</span><span style="font-size: 10pt; line-height: 115%; font-family: &#39;Courier New&#39;; mso-ansi-language: de; mso-fareast-font-family: calibri; mso-fareast-theme-font: minor-latin; mso-fareast-language: en-us; mso-bidi-language: ar-sa"> FactInternetSales</span> </p>
<p>&#160;</p>
</p>
<p>Nun k&#246;nnen wir diese Spalte im Cube verwenden und erzeugen uns auf dessen Basis ein neues Measure Namens &#8222;Scoped Number of Products&#8220;.</p>
<p>&#160;</p>
<p><a href="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/KorrekteMDXBerechnungenmitdenAnalysisSer_87F6/clip_image010.jpg"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="329" alt="clip_image010" src="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/KorrekteMDXBerechnungenmitdenAnalysisSer_87F6/clip_image010_thumb.jpg" width="323" border="0" /></a></p>
<p>&#160;</p>
<p>Dabei ist zu beachten, dass die Aggregat-Funktion, die bei Usage ausgew&#228;hlt wird, sp&#228;ter auch wirklich Anwendung findet. W&#228;hrend bei berechneten Elementen auf jeder Ebene im Cube die Berechnung stattfindet, wird beim SCOPING &#8222;nur&#8220; f&#252;r den explizit &#252;berschriebenen Subcube das MDX verwendet. F&#252;r alle nicht &#252;berschriebenen Bereiche wird normal aggregiert, wobei allerdings die &#8222;neuen&#8220; Werte herangezogen werden. </p>
<p>&#160;</p>
<p>Wir w&#228;hlen also bei Usage die Summe aus und haben unser neues Measure. Nach dem Bereitstellen und Aufbereiten des &#252;berarbeiteten Cubes k&#246;nnen wir das auch schon verwenden, erhalten aber selbstverst&#228;ndlich nur leere Zellen. Die eigentliche Berechnung m&#252;ssen wir nun noch unter &#8222;Calculations&#8220; definieren:</p>
<p>&#160;</p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal; mso-pagination: none; mso-layout-grid-align: none"><span lang="EN-US" style="font-size: 10pt; color: blue; font-family: &#39;Courier New&#39;; mso-ansi-language: en-us">SCOPE</span><span lang="EN-US" style="font-size: 10pt; font-family: &#39;Courier New&#39;; mso-ansi-language: en-us"> ([Measures].[Scoped Number of Products], [Product].[Product].[Product].<span style="color: blue">MEMBERS</span> ); </span>
</p>
</p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal; mso-pagination: none; mso-layout-grid-align: none"><span lang="EN-US" style="font-size: 10pt; font-family: &#39;Courier New&#39;; mso-ansi-language: en-us"><span style="mso-spacerun: yes">&#160;&#160;&#160; </span><span style="color: blue">THIS</span> = 1; </span>
</p>
</p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal; mso-pagination: none; mso-layout-grid-align: none"><span lang="EN-US" style="font-size: 10pt; font-family: &#39;Courier New&#39;; mso-ansi-language: en-us"><span style="mso-spacerun: yes">&#160;&#160;&#160; </span><span style="color: blue">SCOPE</span> ([Product].[Product].[All Products].<span style="color: maroon">UnknownMember</span>); </span>
</p>
</p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal; mso-pagination: none; mso-layout-grid-align: none"><span lang="EN-US" style="font-size: 10pt; font-family: &#39;Courier New&#39;; mso-ansi-language: en-us"><span style="mso-spacerun: yes">&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: blue">THIS</span> = 0; </span>
</p>
</p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal; mso-pagination: none; mso-layout-grid-align: none"><span lang="EN-US" style="font-size: 10pt; font-family: &#39;Courier New&#39;; mso-ansi-language: en-us"><span style="mso-spacerun: yes">&#160;&#160;&#160; </span><span style="color: blue">END</span> <span style="color: blue">SCOPE</span>; </span>
</p>
</p>
<p><span lang="EN-US" style="font-size: 10pt; color: blue; line-height: 115%; font-family: &#39;Courier New&#39;; mso-ansi-language: en-us; mso-fareast-font-family: calibri; mso-fareast-theme-font: minor-latin; mso-fareast-language: en-us; mso-bidi-language: ar-sa">END</span><span lang="EN-US" style="font-size: 10pt; line-height: 115%; font-family: &#39;Courier New&#39;; mso-ansi-language: en-us; mso-fareast-font-family: calibri; mso-fareast-theme-font: minor-latin; mso-fareast-language: en-us; mso-bidi-language: ar-sa"> <span style="color: blue">SCOPE</span>;</span> </p>
<p>&#160;</p>
</p>
<p>F&#252;r alle Elemente des Levels &#8220;Product&#8221; in der Hierarchie &#8220;Product&#8221; der Dimension &#8220;Product&#8221; wird damit der Wert des Measures &#8222;Scoped Number of Products&#8220; auf 1 gesetzt. Alle anderen Ebenen und Hierarchien, wie z. B. der All-Knoten, werden dabei ignoriert, da wir daf&#252;r ja die bereits definierte Summen-Funktion nutzen wollen.</p>
<p>&#160;</p>
<p>Um eine Vergleichbarkeit mit dem alten berechneten Element herzustellen, verhindert das zweite SCOPE lediglich, dass das unsichtbare UnknownMember der Produkt-Hierarchie mitgez&#228;hlt wird.</p>
<p>&#160;</p>
<p>Um zu &#252;berpr&#252;fen, ob die Zahlen passen, nehmen wir das neue Measure nun in unsere erste Abfrage von oben mit auf:</p>
<p>&#160;</p>
<p><a href="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/KorrekteMDXBerechnungenmitdenAnalysisSer_87F6/clip_image012.jpg"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="145" alt="clip_image012" src="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/KorrekteMDXBerechnungenmitdenAnalysisSer_87F6/clip_image012_thumb.jpg" width="476" border="0" /></a></p>
<p>&#160;</p>
<p>Soweit, so gut. Spannender wird es jetzt aber, wenn wir die Kategorien wieder von den Zeilen in den Filter verschieben und nur die ersten beiden Elemente ausw&#228;hlen &#8211; Excel also wieder sein beliebtes SUBSELECT ausf&#252;hrt:</p>
<p>&#160;</p>
<p><a href="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/KorrekteMDXBerechnungenmitdenAnalysisSer_87F6/clip_image014.jpg"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="106" alt="clip_image014" src="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/KorrekteMDXBerechnungenmitdenAnalysisSer_87F6/clip_image014_thumb.jpg" width="321" border="0" /></a></p>
<p>&#160;</p>
<p>Wie erhofft ergibt 35 + 125 nun nicht mehr 606, sondern Excel gibt die korrekte Summe 160 zur&#252;ck. Dadurch, dass wir das Measure auf der untersten Ebene der Produktdimension &#252;berschrieben haben, nutzen die Analysis Services nicht mehr bestehende Aggregate, sondern m&#252;ssen alle betroffenen Produkte zur Laufzeit berechnen. Die anschlie&#223;end stattfindende Aggregation der Werte wird dann nur f&#252;r den betroffenen Subcube, also unter Ber&#252;cksichtigung des Subselects, durchgef&#252;hrt.</p>
<p>&#160;</p>
<p>Um zu zeigen, dass dies nicht nur f&#252;r simples Z&#228;hlen funktioniert, erzeugen wir uns ein weiteres Measure auf Basis unserer Dummy-Spalte, nennen es &#8222;Scoped Ratio to Parent Product&#8220; und erweitern unser MDX-Script um folgenden Ausdruck:</p>
<p>&#160;</p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal; mso-pagination: none; mso-layout-grid-align: none"><span lang="EN-US" style="font-size: 10pt; color: blue; font-family: &#39;Courier New&#39;; mso-ansi-language: en-us">SCOPE</span><span lang="EN-US" style="font-size: 10pt; font-family: &#39;Courier New&#39;; mso-ansi-language: en-us"> ([Measures].[Scoped Ratio to Parent Product], [Product].[Product Model Categories].<span style="color: blue">MEMBERS</span>); </span>
</p>
</p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal; mso-pagination: none; mso-layout-grid-align: none"><span lang="EN-US" style="font-size: 10pt; font-family: &#39;Courier New&#39;; mso-ansi-language: en-us"><span style="mso-spacerun: yes">&#160;&#160;&#160; </span><span style="color: blue">SCOPE</span>(<span style="color: blue">DESCENDANTS</span>([Product].[Product Model Categories].[All Products], , <span style="color: blue">AFTER</span>)); </span>
</p>
</p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal; mso-pagination: none; mso-layout-grid-align: none"><span lang="EN-US" style="font-size: 10pt; font-family: &#39;Courier New&#39;; mso-ansi-language: en-us"><span style="mso-spacerun: yes">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: blue">THIS</span> = [Measures].[Sales Amount] </span>
</p>
</p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal; mso-pagination: none; mso-layout-grid-align: none"><span lang="EN-US" style="font-size: 10pt; font-family: &#39;Courier New&#39;; mso-ansi-language: en-us"><span style="mso-spacerun: yes">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span>/ ( [Product].[Product Model Categories].<span style="color: maroon">CurrentMember</span>.<span style="color: maroon">Parent</span>, </span>
</p>
</p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal; mso-pagination: none; mso-layout-grid-align: none"><span lang="EN-US" style="font-size: 10pt; font-family: &#39;Courier New&#39;; mso-ansi-language: en-us"><span style="mso-spacerun: yes">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span>[Measures].[Sales Amount] ); </span>
</p>
</p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal; mso-pagination: none; mso-layout-grid-align: none"><span lang="EN-US" style="font-size: 10pt; font-family: &#39;Courier New&#39;; mso-ansi-language: en-us"><span style="mso-spacerun: yes">&#160;&#160;&#160; </span><span style="color: blue">END</span> <span style="color: blue">SCOPE</span>; </span>
</p>
</p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal; mso-pagination: none; mso-layout-grid-align: none"><span lang="EN-US" style="font-size: 10pt; font-family: &#39;Courier New&#39;; mso-ansi-language: en-us"><span style="mso-spacerun: yes">&#160;&#160;&#160; </span><span style="color: blue">Format_String</span>(<span style="color: blue">THIS</span>) = <span style="color: #a31515">&quot;Percent&quot;</span> ; </span>
</p>
</p>
<p><span lang="EN-US" style="font-size: 10pt; color: blue; line-height: 115%; font-family: &#39;Courier New&#39;; mso-ansi-language: en-us; mso-fareast-font-family: calibri; mso-fareast-theme-font: minor-latin; mso-fareast-language: en-us; mso-bidi-language: ar-sa">END</span><span lang="EN-US" style="font-size: 10pt; line-height: 115%; font-family: &#39;Courier New&#39;; mso-ansi-language: en-us; mso-fareast-font-family: calibri; mso-fareast-theme-font: minor-latin; mso-fareast-language: en-us; mso-bidi-language: ar-sa"> <span style="color: blue">SCOPE</span>;</span> </p>
<p>&#160;</p>
<p>Dabei sorgt das DESCENDANTS(&#8230;) daf&#252;r, dass alle Elemente der Hierarchie &#8220;Product Model Categories&#8221; au&#223;er dem All-Knoten &#252;berschrieben werden. Das Ergebnis in Excel sieht dann folgenderma&#223;en aus:</p>
<p>&#160;</p>
<p><a href="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/KorrekteMDXBerechnungenmitdenAnalysisSer_87F6/clip_image016.jpg"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="106" alt="clip_image016" src="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/KorrekteMDXBerechnungenmitdenAnalysisSer_87F6/clip_image016_thumb.jpg" width="387" border="0" /></a></p>
<p>&#160;</p>
<p>Auch hier sorgt das &#220;berschreiben auf unterster Ebene daf&#252;r, dass die Berechnung richtig funktioniert. In dem Augenblick, in dem die einzelnen Knoten der ausgewerteten Hierarchie berechnet werden, gibt es eben immer ein CurrentMember, egal ob nun ein oder mehrere Knoten ausgew&#228;hlt sind.</p>
<p>&#160;</p>
<p><b><u>Einschr&#228;nkungen</u></b></p>
<p>Zugegeben, habe ich mir das ganze hier etwas leicht gemacht. Die beiden Berechnungen einfach zu summieren, macht n&#228;mlich eigentlich keinen Sinn. Sowohl die Anzahl der Produkte, als auch die Prozente sind sogenannte semi-additive Measures, die eben nicht einfach summiert werden d&#252;rfen. F&#252;r beide fehlt also mindestens eine Sonderbehandlung f&#252;r die Zeitdimension, die durch Nutzung anderer Aggregatfunktionen oder erweiterter SCOPE-Statements erreicht werden k&#246;nnte, die den Rahmen dieses Beitrags sprengen w&#252;rden.</p>
<p>&#160;</p>
<p>Au&#223;erdem muss ich davor warnen jetzt ab sofort alle berechneten Elemente durch solche SCOPEs abzul&#246;sen, denn das ganze hat nat&#252;rlich einen Haken. Der Grund, warum das Ganze funktioniert, n&#228;mlich das Berechnen auf unteren Ebenen, hat gleichzeitig negative Auswirkungen auf die Performance. Es k&#246;nnen eben nicht mehr vorberechnete Werte aus den Aggregationen oder dem Cache &#252;bernommen werden. Bei jeder Abfrage, die sonst nur wenige Zellen zur Berechnung h&#228;tte nutzen m&#252;ssen, muss jetzt unter Umst&#228;nden ein Vielfaches an Daten ber&#252;cksichtigt werden, um das gew&#252;nschte Ergebnis zu erhalten. </p>
<p>&#160;</p>
<p>Nichts desto trotz zeigt das Ganze, dass es m&#246;glich ist, Berechnungen so zu definieren, dass sie Multiselect-f&#228;hig sind, obwohl sie Funktionen wie EXISTING oder CurrentMember ben&#246;tigen. Wer mit relativ wenig Daten arbeitet, oder wem es nicht gelingt seinen Nutzern das Multiselect in Excel auszureden, der kommt so vielleicht zu einer L&#246;sung.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ixto.de/blog/sql-server-2005/mdx-2005/korrekte-mdx-berechnungen-mit-den-analysis-services-trotz-multiselect/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Dimensionsdatensicherheit als Fehlerquelle f&#252;r &quot;unsaubere&quot; Sets</title>
		<link>http://www.ixto.de/blog/sql-server-2005/mdx-2005/dimensionsdatensicherheit-als-fehlerquelle-fr-unsaubere-sets/</link>
		<comments>http://www.ixto.de/blog/sql-server-2005/mdx-2005/dimensionsdatensicherheit-als-fehlerquelle-fr-unsaubere-sets/#comments</comments>
		<pubDate>Mon, 28 Jul 2008 16:44:39 +0000</pubDate>
		<dc:creator>Markus Schechner</dc:creator>
				<category><![CDATA[MDX im SQL Server 2005]]></category>

		<guid isPermaLink="false">http://www.ixto.de/blog/allgemein/dimensionsdatensicherheit-als-fehlerquelle-fr-unsaubere-sets/</guid>
		<description><![CDATA[Hallo liebe Reportbauer, MDXler und alle die es werden wollen,
ich bin vor kurzem bei einem Kunden &#252;ber ein Ph&#228;nomen gestolpert, dass ich Euch nicht vorenthalten will.
&#160;
Wie immer wieder von mir gepredigt wird, arbeiten wir in der Regel zur Ausklammerung bestimmter Dimensionsknoten mit so genannten &#8222;Negativ-Listen&#8220;. Das bedeutet, wenn wir aus der Dimension Buchstaben die Knoten [...]]]></description>
			<content:encoded><![CDATA[<p>Hallo liebe Reportbauer, MDXler und alle die es werden wollen,</p>
<p>ich bin vor kurzem bei einem Kunden &#252;ber ein Ph&#228;nomen gestolpert, dass ich Euch nicht vorenthalten will.</p>
<p>&#160;</p>
<p>Wie immer wieder von mir gepredigt wird, arbeiten wir in der Regel zur Ausklammerung bestimmter Dimensionsknoten mit so genannten &#8222;Negativ-Listen&#8220;. Das bedeutet, wenn wir aus der Dimension Buchstaben die Knoten A, B und E sehen wollen sagen wir nicht {A, B, E} sondern {Buchstaben.ALLE &#8211; {C, D}}. Dadurch w&#252;rden neue Knoten in der Dimension (z.B. der neu eingef&#252;hrte Buchstabe F <img src='http://www.ixto.de/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> ) nicht per Default unterdr&#252;ckt, sondern w&#228;ren erst mal sichtbar. In den meisten echten Anwendungsf&#228;llen ist diese Negativ-Liste oft auch deutlich k&#252;rzer als die Positiv-Liste. Aber genug &#252;ber den Sinn und Unsinn von Negativ-Listen, das Statement</p>
<p>&#160;</p>
<p><font color="#0000ff" size="2">SELECT</font>
</p>
<p>   <font size="2">{}</font>
<p><font color="#0000ff" size="2">ON</font><font size="2"> </font><font color="#0000ff" size="2">COLUMNS</font><font size="2">,</font></p>
<p>{[Product].[Category].[Accessories], [Product].[Category].[Bikes], [Product].[Category].[Clothing]}</p>
<p><font color="#0000ff" size="2">ON</font><font size="2"> </font><font color="#0000ff" size="2">ROWS</font></p>
<p>FROM</p>
<p><font size="2">[Adventure Works]</font></p>
<p>&#160;</p>
</p>
<p> liefert das gleiche Ergebnis zur&#252;ck, wie</p>
<p>&#160;</p>
<p><font color="#0000ff" size="2">SELECT</font>
</p>
<p>   <font size="2">{}</font>
<p><font color="#0000ff" size="2">ON</font><font size="2"> </font><font color="#0000ff" size="2">COLUMNS</font><font size="2">,</font></p>
<p>{[Product].[Category].[Category].</p>
<p><font color="#0000ff" size="2">MEMBERS</font><font size="2"> &#8211; [Product].[Category].[Components]} </font><font color="#0000ff" size="2">ON</font><font size="2"> </font><font color="#0000ff" size="2">ROWS</font></p>
<p>FROM</p>
<p><font size="2">[Adventure Works]</font></p>
<p>&#160;</p>
</p>
<p> Nun hat sich innerhalb des besagten Kundenprojektes heimlich durchgesetzt, dass die abgek&#252;rzte Schreibweise verwendet wird, also {&#8211; {C, D}} statt { Buchstaben.ALLE &#8211; {C, D}}. Also auch die folgende dritte Variante hat das gleiche Ergebnis wie die oberen beiden.</p>
<p>&#160;</p>
<p><font color="#0000ff" size="2">SELECT</font>
</p>
<p>   <font size="2">{}</font>
<p><font color="#0000ff" size="2">ON</font><font size="2"> </font><font color="#0000ff" size="2">COLUMNS</font><font size="2">,</font></p>
<p>{-{[Product].[Category].[Components]}}</p>
<p><font color="#0000ff" size="2">ON</font><font size="2"> </font><font color="#0000ff" size="2">ROWS</font></p>
<p>FROM</p>
<p><font size="2">[Adventure Works]</font></p>
<p>&#160;</p>
</p>
<p> Dies hat eigentlich auch super funktioniert, ist an K&#252;rze kaum noch zu &#252;bertreffen UND SOLLTE TROTZDEM NIE WIEDER GETAN WERDEN <img src='http://www.ixto.de/blog/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p>&#160;</p>
<p>Implizit erkennt der AS bei dieser Schreibweise, welche Elemente auf der linken Seite dieses Komplements geh&#246;ren, n&#228;mlich Buchstaben.ALLE. Sobald aber eine Dimensionssicherheit ins Spiel kommt wird&#8217;s gef&#228;hrlich. AS sucht die Knoten dann nur noch in dem Bereich in dem der Nutzer berechtigt ist. Wenn er den Knoten da nicht findet, wei&#223; er nicht, ob er nicht existiert, oder ob er nicht berechtigt ist und ersetzt ihn durch die leere Menge ({}).</p>
<p>&#160;</p>
<p>Aus { Buchstaben.ALLE &#8211; {C, D}} w&#252;rde also intern { Buchstaben.ALLE &#8211; { }}. Nicht schlimm, funktioniert super. Ihr k&#246;nnt Euch aber denken, dass das nicht mehr funktioniert, wenn aus {&#8211; {C, D}} durch dieses Verhalten {-{}} wird. Und das B&#246;se daran ist, dass das erst auftritt wenn der erste eingeschr&#228;nkte Nutzer darauf zugreift. F&#252;r Euch als Entwickler sieht es aus als w&#228;re alles fein, w&#228;hrend der arme Benutzer mit der Meldung &quot;<em>Die Menge muss eine einzige Hierarchie aufweisen, um mit dem Komplementoperator verwendet zu werden.</em>&quot; bzw. &quot;<em>The set must have a single hierarchy to be used with the complement operator.</em>&quot; begr&#252;&#223;t wird.</p>
<p>&#160;</p>
<p>Also kurz:</p>
<p>Niemals {&#8211; {C, D}}</p>
<p>Immer { Buchstaben.ALLE &#8211; {C, D}}&#160; oder aber EXCEPT(Buchstaben.ALLE, {C, D})</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ixto.de/blog/sql-server-2005/mdx-2005/dimensionsdatensicherheit-als-fehlerquelle-fr-unsaubere-sets/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
