<?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/"
	xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"
	xmlns:media="http://search.yahoo.com/mrss/"
>

<channel>
	<title>Dave's Adventures in Business Intelligence &#187; Fan / Chasm Trap</title>
	<atom:link href="http://www.dagira.com/category/design/fan-chasm-trap/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.dagira.com</link>
	<description>...you are in a twisty maze of passageways, all different...</description>
	<lastBuildDate>Tue, 31 Aug 2010 01:40:55 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
		<!-- podcast_generator="podPress/8.8" -->
		<copyright>&#xA9; </copyright>
		<managingEditor>blogmaster@dagira.com ()</managingEditor>
		<webMaster>blogmaster@dagira.com()</webMaster>
		<category></category>
		<ttl>1440</ttl>
		<itunes:keywords></itunes:keywords>
		<itunes:subtitle></itunes:subtitle>
		<itunes:summary>...you are in a twisty maze of passageways, all different...</itunes:summary>
		<itunes:author></itunes:author>
		<itunes:category text="Society &amp; Culture"/>
		<itunes:owner>
			<itunes:name></itunes:name>
			<itunes:email>blogmaster@dagira.com</itunes:email>
		</itunes:owner>
		<itunes:block>No</itunes:block>
		<itunes:explicit>no</itunes:explicit>
		<itunes:image href="http://www.dagira.com/wp-content/plugins/podpress/images/powered_by_podpress_large.jpg" />
		<image>
			<url>http://www.dagira.com/wp-content/plugins/podpress/images/powered_by_podpress.jpg</url>
			<title>Dave's Adventures in Business Intelligence</title>
			<link>http://www.dagira.com</link>
			<width>144</width>
			<height>144</height>
		</image>
		<item>
		<title>ZEN and the ART of Universe Design Presentation Posted</title>
		<link>http://www.dagira.com/2009/07/27/zen-and-the-art-of-universe-design-presentation-posted/</link>
		<comments>http://www.dagira.com/2009/07/27/zen-and-the-art-of-universe-design-presentation-posted/#comments</comments>
		<pubDate>Mon, 27 Jul 2009 12:39:27 +0000</pubDate>
		<dc:creator>Dave Rathbun</dc:creator>
				<category><![CDATA[Fan / Chasm Trap]]></category>
		<category><![CDATA[Universe Contexts]]></category>
		<category><![CDATA[Universe Design]]></category>

		<guid isPermaLink="false">http://www.dagira.com/?p=171</guid>
		<description><![CDATA[I did a fun presentation (at least I had fun) at the New York user group a few years back. I found the original download package and have posted it on the presentations page on this site. The download package includes the presentation in Adobe PDF format, several universes, some Microsoft Access database files, some [...]]]></description>
			<content:encoded><![CDATA[<p>I did a fun presentation (at least I had fun) at the New York user group a few years back. I found the original download package and have posted it on the <a href="http://www.dagira.com/conference-presentations/">presentations page</a> on this site. The download package includes the presentation in Adobe PDF format, several universes, some Microsoft Access database files, some sample reports&#8230; basically everything you need to go through the slides and review the examples.</p>
<p>There is a &#8220;readme&#8221; file that contains notes on how to get everything working. The reports and universes were originally built in version 5, but should be usable in any current version (up through XI 3.1 as I type this). The demonstration reports were all built in Desktop Intelligence.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dagira.com/2009/07/27/zen-and-the-art-of-universe-design-presentation-posted/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Is &#8220;One Context Per Fact Table&#8221; a True Statement?</title>
		<link>http://www.dagira.com/2008/04/30/is-one-context-per-fact-table-a-true-statement/</link>
		<comments>http://www.dagira.com/2008/04/30/is-one-context-per-fact-table-a-true-statement/#comments</comments>
		<pubDate>Thu, 01 May 2008 03:20:08 +0000</pubDate>
		<dc:creator>Dave Rathbun</dc:creator>
				<category><![CDATA[Fan / Chasm Trap]]></category>
		<category><![CDATA[Universe Contexts]]></category>
		<category><![CDATA[Universe Design]]></category>

		<guid isPermaLink="false">http://www.dagira.com/?p=83</guid>
		<description><![CDATA[The other day I was talking to someone about contexts in a universe and they offered the typical response. You probably know the one&#8230; it says that you should set up one context per fact table. If you read many posts on BOB then you&#8217;ll see that phrase quoted quite a bit. The question is: [...]]]></description>
			<content:encoded><![CDATA[<p>The other day I was talking to someone about contexts in a universe and they offered the typical response. You probably know the one&#8230; it says that you should set up one context per fact table. If you read many posts on BOB then you&#8217;ll see that phrase quoted quite a bit. The question is: Is this the truth, the whole truth, and nothing but the truth?</p>
<p>No, it is not. </p>
<p><span id="more-83"></span></p>
<p>Contexts are designed to show which joins can be used together. If you have a multi-fact datawarehouse then almost certainly your fact tables contain different information, and therefore should not be linked (joined) together. Thus, you separate them out with contexts. Unfortunately that&#8217;s an incomplete explanation at best, and misleading at worst. The implication that some folks might take away from this is that if they don&#8217;t have &#8220;fact&#8221; tables then they don&#8217;t need contexts.</p>
<p>That is a very dangerous assumption. To see why, let&#8217;s look at some of the math behind some relational database concepts.</p>
<h3>Cartesian Products</h3>
<p>Wikipedia defines a cartesian product as follows:</p>
<blockquote><p>Specifically, the Cartesian product of two sets X (for example the points on an x-axis) and Y (for example the points on a y-axis), denoted X Ã— Y, is the set of all possible ordered pairs whose first component is a member of X and whose second component is a member of Y (e.g. the whole of the x-y plane):</p>
<p>For example, the Cartesian product of the thirteen-element set of standard playing card ranks {Ace, King, Queen, Jack, 10, 9, 8, 7, 6, 5, 4, 3, 2} and the four-element set of card suits {â™ , â™¥, â™¦, â™£} is the 52-element set of playing cards {(Ace, â™ ), (King, â™ ), &#8230;, (2, â™ ), (Ace, â™¥), &#8230;, (3, â™£), (2, â™£)}. The Cartesian product has 52 elements because that is the product of 13 times 4.</p></blockquote>
<p>Hm. Well. Ok. What does that mean?</p>
<p>It essentially means that you match every element from one set with every element of the next set, resulting in a dramatic increase in the number of combinations or <em>tuples</em>. A <em>tuple</em> in database terms is a result row that can be obtained via a query.</p>
<p>If you replace the word &#8220;set&#8221; with &#8220;table&#8221; and the word &#8220;element&#8221; with &#8220;row&#8221; you get an application of a Cartesian Product that is associated with database queries. In this case you get every row from the first table related (joined) to every row in a second table. This is generally not a desirable result. <img src='http://www.dagira.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h3>What About Partial Cartesian Products?</h3>
<p>The SQL generator used by Business Objects allows you to check for and prevent (or warn against) Cartesian Product queries. This means that a user will likely never end up with a true Cartesian Product without at least being warned about it. But the SQL generator will not detect what I will call a &#8220;partial&#8221; product without help. Here&#8217;s an example.</p>
<p><img src="/tips/one_context_per_fact/erd.png" width="595" height="78" border="0" alt="erd image" title="Sample ERD from Summit Sporting Goods" /><br />
<em>Note: This simple ERD is from a database I use for a number of presentations, and eventually you&#8217;ll be able to download it from the site.</em></p>
<p>In this diagram you can see relationships from <code>customers</code> to <code>orders</code>, from <code>orders</code> to <code>lines</code>, from <code>lines</code> to <code>items</code>, and from <code>items</code> to <code>prices</code>. Each item can have multiple prices over time. Each item can also appear on more than one order line. A customer can have many orders, which can have many lines, and so on.</p>
<p>There are no loops in this diagram. There are no fact tables. Do I need any contexts?</p>
<h3>Presenting the Correct Picture</h3>
<p>The answer is &#8220;Yes&#8221;, I need a context in a universe that contains this simple model. There is a relationship between <code>items</code> and <code>prices</code>, and another relationship between <code>items</code> and <code>lines</code>. But those two relationships are <strong>separate and distinct from each other</strong> and as a result cannot be used together.</p>
<p>Let&#8217;s assume for a moment that there is an item with <code>item_id</code> of 100. Let&#8217;s assume that the items has had only one price throughout its history, and that it&#8217;s $10. Finally, let&#8217;s assume that this item has appeared on 10 different order lines. If I run this SQL I will get the correct result:</p>
<pre>SELECT	items.item_name
,	prices.price
,	lines.qty
FROM	items i
,	prices p
,	lines l
WHERE	items.item_id = prices.item_id
AND	items.item_id = lines.item_id</pre>
<p>I should get ten rows of data back from this query, and I will.</p>
<p>The problem is that if the item changes prices halfway through my ten orders I will get two results from the price table. Those two rows will be combined with ten rows from the lines table because the relationship through the items table is a partial Cartesian product. <img src='http://www.dagira.com/wp-includes/images/smilies/icon_eek.gif' alt=':shock:' class='wp-smiley' />  This error will not be detected or prevented by the SQL generator, and the user will be presented with incorrect results. There will be two price values for each and every item row, with a net of 2 * 10 or 20 result rows instead of the expected 10. I don&#8217;t get a full Cartesian product between every line and every price because of the joins through the items table, but I still have an inflated set of rows.</p>
<p>I might try to solve this by creating a join from <code>lines</code> to <code>prices</code> and matching by price but that has then created a loop from <code>lines</code> to <code>prices</code> to <code>items</code> and back to <code>lines</code>. And frankly it&#8217;s not the correct thing to do.</p>
<h3>Fixing The Partial Cartesian Product</h3>
<p>The proper solution is to isolate the incompatible relationships. The tool that we have to do that is a context. Since the item table has two functions in this universe I will separate out those two functions using two contexts:</p>
<ul>
<li>First Context:<br />
Customers &#8211; Orders &#8211; Lines &#8211; Items</li>
<li>Second Context:<br />
Items &#8211; Prices</li>
</ul>
<p>The first context is designed to let me report on order history. The second context is designed to let me report on item price history. The pricing history is a completely separate subject area from order history, and by splitting them out with contexts I can ensure that a user will never be provided with an incorrect or misleading result set.</p>
<p>That should always be the goal of a universe designer. <img src='http://www.dagira.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h3>Conclusion</h3>
<p>I don&#8217;t have any fact tables in the ERD I showed above. I don&#8217;t have any loops. Yet despite this I need to set up contexts in order to generate the correct query results from my universe. Now here&#8217;s the fun part: you could provide me the exact same set of tables but number them one through five rather than give me the table name and some indication as to the purpose. If you do that, I can <strong>still</strong> set up the universe correctly, even though I don&#8217;t have a clue what is stored in each table.</p>
<p>How is that possible?</p>
<p>It&#8217;s all driven by the relationships between the tables. As long I know the type of relationship (one &#8211; one, one &#8211; many, many &#8211; many) I can create a correct universe. That&#8217;s the subject for my next post on Contexts where I will explain how it works and why the name &#8220;chasm trap&#8221; is appropriate. <img src='http://www.dagira.com/wp-includes/images/smilies/icon_cool.gif' alt='8-)' class='wp-smiley' /> </p>
<p><strong>Related Links</strong></p>
<ul>
<li><a href="http://en.wikipedia.org/wiki/Cartesian_Product">Wiki on Cartesian Products</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.dagira.com/2008/04/30/is-one-context-per-fact-table-a-true-statement/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>What Is a Context Anyway?</title>
		<link>http://www.dagira.com/2008/03/10/what-is-a-context-anyway/</link>
		<comments>http://www.dagira.com/2008/03/10/what-is-a-context-anyway/#comments</comments>
		<pubDate>Mon, 10 Mar 2008 15:09:07 +0000</pubDate>
		<dc:creator>Dave Rathbun</dc:creator>
				<category><![CDATA[Fan / Chasm Trap]]></category>
		<category><![CDATA[Universe Contexts]]></category>
		<category><![CDATA[Universe Design]]></category>

		<guid isPermaLink="false">http://www.dagira.com/2008/03/10/what-is-a-context-anyway/</guid>
		<description><![CDATA[A few days ago I finally got started on what will become a series of posts about fan and chasm traps. The post was &#8220;Do I Have a Fan Trap?&#8221; and it included a definition of a fan trap in a universe and showed a basic solution. However, it also mentioned that the basic solution [...]]]></description>
			<content:encoded><![CDATA[<p>A few days ago I finally got started on what will become a series of posts about fan and chasm traps. The post was <a href="http://www.dagira.com/2008/03/03/do-i-have-a-fan-trap/">&#8220;Do I Have a Fan Trap?&#8221;</a> and it included a definition of a fan trap in a universe and showed a basic solution. However, it also mentioned that the basic solution would not work in most cases, and that contexts would be required for a more complete solution. If you are new to the Universe Designer, or even if you just have not worked with contexts that much, the first step is understanding exactly what a context does for you. That is what I hope to do with this post.</p>
<p><span id="more-70"></span></p>
<h3>Just the Facts</h3>
<p>One of the comments that you will see quite frequently on BOB is that you need one context for each fact table. That assumes that you have fact tables. <img src='http://www.dagira.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  It turns out that the statement is, in fact (heh, pun intended <img src='http://www.dagira.com/wp-includes/images/smilies/icon_razz.gif' alt=':-P' class='wp-smiley' />  ), true, but why is that? What is it about a fact table that requires a context?</p>
<h3>Universe Structure</h3>
<p>A universe is a combination of two things: the structure (map) of the tables and the required joins, and the classes and objects that are presented to the user as the interface to the data. For the most part contexts are associated with the first part (structure) although they do have a user interface component as well. In the last post on this subject I included this quote:</p>
<blockquote><p>As a designer you cannot control which objects a user selects to use on a query. You are not building a specific query, you are building a <strong>framework</strong> for any query.</p></blockquote>
<p>What this means is that as a designer you include all of the potential joins in your universe structure without knowing in advance which query path a user is going to require for any given report. In most cases that isn&#8217;t a problem. But in some cases it might be, and that&#8217;s where contexts become valuable.</p>
<h3>Context Definition</h3>
<p>A context is nothing more than a set of joins. That&#8217;s it. If you were expecting something more complicated, I&#8217;m afraid that you&#8217;re going to be disappointed. <img src='http://www.dagira.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  The complicated part is how that set of joins is identified and then utilized, and I will talk more about that a bit later. For now, let me talk about getting home from work.</p>
<p>There is a train station at your office building. There is another train station at your house. Think about tables in your universe as stops you might make on the train. The joins are the routes that the train system offers. Each trip that you take has a specific starting point (a table), an ending point (another table), and a route in between (zero or more tables). Normally you take the route home that includes a stop at your neighborhood store for milk and other groceries. But occasionally you don&#8217;t need milk and instead you stop at the news stand to pick up a magazine or something else to read that evening. That stop requires you to take a different route home. Something like this:</p>
<p><img src="/tips/what_is_a_context/two_routes_home.jpg" /></p>
<p>Both trips end up with you getting home, but each trip provides different information. You either come home with a gallon of milk or a magazine. <img src='http://www.dagira.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h3>Making Two Trips</h3>
<p>So what do you do if you need both a magazine and some milk to go with it? In that case you have to make two stops. But the only way you can do it is to take the first route, and then return back to work and take the second route to pick up the magazine. Or you could clone yourself and take two trips at the same time. That is essentially what happens if the &#8220;Multiple SQL Statements for Each Context&#8221; option is enabled in your universe; you have the option to make more than one trip. If that option is not enabled, then you simply are not allowed to pick up both milk and a magazine.</p>
<p>What if you are at work, and you are ready to take the train home, and you don&#8217;t need either of those? The choice before you at that point is: Which route do you want to take to get home? Since you have not made a decision that eliminates one route (context) or the other you have to decide before you start your trip which way to go. (Maybe you&#8217;ll take a shortcut, but that&#8217;s a different technique. <img src='http://www.dagira.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':-D' class='wp-smiley' />  ) This type of query is called an &#8220;ambiguous query&#8221; because there is nothing about your trip that predetermines the route to take based on the end points (work and home). In this case the user (either the person riding the train or the user writing the query) will have to make the selection manually. In the case of a query writer the decision is done by answering a prompt with a list of available contexts (routes).</p>
<p>In theory, the route doesn&#8217;t matter, because you just want to get home and aren&#8217;t stopping to pick anything up on the way. Either route will work, but there is nothing about your trip plan that identifies or requires a specific route. There is an option for &#8220;Allow selection of multiple contexts&#8221; that is off by default. This really a strange option, as it allows you to make two (or more) trips on an ambiguous query.</p>
<p>Using the same scenario as earlier it would be like taking two trips home (both routes) without making any stops along the way just because you can&#8217;t make up your mind which way to go. Doesn&#8217;t make much sense when riding a train, and it doesn&#8217;t make much sense for a database query either. If you don&#8217;t need anything along the way, don&#8217;t make two trips. You just end up wasting time.</p>
<h3>How Do I Define My Routes?</h3>
<p>If a context is nothing more than a set of joins, why is it such a big deal? The first reason is that it allows you to make one larger universe rather than two smaller ones. I can make a &#8220;Milk and Magazine&#8221; universe instead of having two separate universes. Without contexts I would have to take both routes everytime I wanted to get home from work. Not only is that a waste of time, it would quite probably end up generating the wrong results. The train analogy is starting to fall apart at this point, I think. <img src='http://www.dagira.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>But how do I know which routes (joins) to include in a trip (context)? There are certain signals that you can read (think of them as traffic lights) that will tell you which routes can be used together. These signals are given by the cardinality of the joins, which essentially provides information about how far you can travel on the route before changing trains. Erm. Contexts. <img src='http://www.dagira.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' />  I intend for that to be my next post in this series, as this post was intended to define what a context is and provide some examples of the concept.</p>
<h3>Summary</h3>
<p>Here are the most important points for this post, as I see them:</p>
<ul>
<li>A context is nothing more than a set of joins</li>
<li>The setting Multiple SQL Statements for each Context allows you to split a single query into two or more passes based on the contexts in your universe.</li>
<li>The setting &#8220;Allow selection of multiple contexts&#8221; is off by default and probably should stay off. It doesn&#8217;t really seem to help anything.</li>
</ul>
<p>The next post will talk about how to identify the set of joins that will be used to make up a context in your universe, and it will also explain why every join has to be in at least one context.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dagira.com/2008/03/10/what-is-a-context-anyway/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>Do I Have a Fan Trap?</title>
		<link>http://www.dagira.com/2008/03/03/do-i-have-a-fan-trap/</link>
		<comments>http://www.dagira.com/2008/03/03/do-i-have-a-fan-trap/#comments</comments>
		<pubDate>Mon, 03 Mar 2008 20:00:52 +0000</pubDate>
		<dc:creator>Dave Rathbun</dc:creator>
				<category><![CDATA[Fan / Chasm Trap]]></category>
		<category><![CDATA[Universe Design]]></category>

		<guid isPermaLink="false">http://www.dagira.com/2008/03/03/do-i-have-a-fan-trap/</guid>
		<description><![CDATA[I started to write this a long time ago, but a few things (okay, lots of things) got in the way. I did manage to write a brief introduction a while back but that&#8217;s as far as it got. So today I want to write at least a little bit more about fan traps in [...]]]></description>
			<content:encoded><![CDATA[<p>I started to write this a long time ago, but a few things (okay, lots of things) got in the way. I did manage to write a brief introduction a while back but that&#8217;s as far as it got. So today I want to write at least a little bit more about fan traps in particular.</p>
<p><span id="more-66"></span></p>
<h3>What is a Fan Trap?</h3>
<p>A fan trap occurs when joins &#8220;fan out&#8221; over multiple one -< many relationships in a row. For example:</p>
<p><code>A -< B -< C</code></p>
<p>This is one of the reasons why it is important to set cardinalities in your universe design. If you don&#8217;t set the cardinalities it becomes more difficult to identify fan traps (and other design issues). I frequently get asked in Designer training classes if the cardinality changes the way the joins are written. The answer is that it will not. But it could change how many joins are included in a single query. <img src='http://www.dagira.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h3>Sample Fan Trap Data</h3>
<p>It&#8217;s a subtle issue, so let me demonstrate with a simple example. I will use two hypothetical tables for this example. First is a table used to store order information, and the second is used to store details about the items for the order.</p>
<pre>create table orders
(order_id number(8) not null
,order_date date not null
,order_budget decimal(11,2) not null);

create table order_lines
(order_line_id number(11) not null
,order_id number(8) not null
,item_id number(11) not null
,order_qty number(5) not null);</pre>
<p>These are very simple tables, and the syntax may not be exactly correct for all databases. There will be an order number object built from the <code>orders.order_id</code> column. I will build a <strong>Total Order Budget</strong> measure object from the <code>orders.order_budget</code> column. And I will also create a measure object called <strong>Total Order Quantity</strong> using the formula <code>sum(order_lines.qty)</code>. This gives me one dimension object and two basic measure objects.</p>
<p>Here is what the raw data will look like:</p>
<table class="blogtable">
<tr>
<th>Order Number</th>
<th>Budget</th>
<th>Quantity</th>
</tr>
<tr class="alt">
<td>1</td>
<td>500</td>
<td>10</td>
</tr>
<tr>
<td>1</td>
<td>500</td>
<td>20</td>
</tr>
<tr class="alt">
<td>1</td>
<td>500</td>
<td>25</td>
</tr>
<tr>
<td>1</td>
<td>500</td>
<td>10</td>
</tr>
<tr class="alt">
<td>2</td>
<td>1500</td>
<td>10</td>
</tr>
<tr>
<td>2</td>
<td>1500</td>
<td>10</td>
</tr>
<tr class="alt">
<td>2</td>
<td>1500</td>
<td>5</td>
</tr>
</table>
<h3>Before We Go On, A Brief Aside&#8230;</h3>
<p>One of the statements that I make frequently in the Designer training class is this:</p>
<blockquote><p>As a designer you cannot control which objects a user selects to use on a query. You are not building a specific query, you are building a <strong>framework</strong> for any query.</p></blockquote>
<p>Great. Now what does it mean? <img src='http://www.dagira.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>It means that the objects I have created above will generate the wrong result if they are not used correctly. Since I cannot control how they are used, I need to fix the mistake before it occurs. The mistake in this case is the Fan Trap.</p>
<h3>A Simple Query</h3>
<p>If I write this sql using the data above I will get the results shown below. Everything looks fine.</p>
<p><code>select orders.order_id<br />
, sum(orders.order_budget)<br />
from orders<br />
group by order_id</code></p>
<table class="blogtable">
<tr>
<th>Order Number</th>
<th>Total Order Budget</th>
</tr>
<tr class="alt">
<td>1</td>
<td>500</td>
</tr>
<tr>
<td>2</td>
<td>1500</td>
</tr>
</table>
<p>It all works because of the &#8220;group by&#8221; clause that is automatically generated in my SQL. And it only works because I have not included anything from the order lines table. What happens if I (or a user) were to select all three of my objects? </p>
<h3>Fan Trap Demonstrated</h3>
<p>If I included all three of the objects from my imaginary universe I would get this sql code, and the following results:</p>
<p><code>select orders.order_id<br />
, sum(orders.order_budget)<br />
, sum(order_lines.order_qty)<br />
from orders<br />
, order_lines<br />
where orders.order_id = order_lines.order_id<br />
group by orders.order_id</code></p>
<table class="blogtable">
<tr>
<th>Order Number</th>
<th>Total Order Budget</th>
<th>Total Order Quantity</th>
</tr>
<tr class="alt">
<td>1</td>
<td>2000</td>
<td>65</td>
</tr>
<tr>
<td>2</td>
<td>4500</td>
<td>25</td>
</tr>
</table>
<p>Anybody see a problem with this?</p>
<p>The issue is that the line item total (sum) is correct, but the header total budget (also a sum) is way too high. If you look back at the raw data shown earlier, you might notice that the budget amount has been multiplied by the number of line items in the second table. This is a fan trap in action. The number of lines in the detail table has an impact on the measures from the header table.</p>
<h3>Simple Fan Trap Solution</h3>
<p>In this case where I only have measure objects from the detail table there is a very simple solution. I would open my universe and mark the &#8220;Multiple SQL Statements for each Measure&#8221; checkbox. And here is where the cardinality settings become important. Back at the beginning of this post I said this, or something along these lines:</p>
<blockquote><p>Cardinality won&#8217;t change the logic of how joins work, but it might change which joins are included in your query.</p></blockquote>
<p>What this means it when the SQL generator sees the measures and notes that they are spread across a one-many join, it will split the query into two passes and then merge the results back together. So instead of the infated results shown above I will get these two sets of data:</p>
<table class="blogtable">
<tr>
<th>Order Number</th>
<th>Total Order Budget</th>
</tr>
<tr class="alt">
<td>1</td>
<td>500</td>
</tr>
<tr>
<td>2</td>
<td>1500</td>
</tr>
</table>
<p />
<table class="blogtable">
<tr>
<th>Order Number</th>
<th>Total Order Quantity</th>
</tr>
<tr class="alt">
<td>1</td>
<td>65</td>
</tr>
<tr>
<td>2</td>
<td>25</td>
</tr>
</table>
<p>There were only two rows processed by the first query, and seven rows processed by the second query. There are two rows in each result set because of the &#8220;group by&#8221; clause. And when the query results are merged back together (in a process that is completely transparent to the user, by the way) they will be correct.</p>
<h3>So Far, So Good&#8230;</h3>
<p>The problem is this is not a complete solution. As long as I only have measure objects from the lower (more detailed) table then this shortcut will work. And as long as I never <strong>ever</strong> add a new table to the universe, or add a new dimension or detail object, it will continue to work. But it&#8217;s a fragile solution, because nothing has really been fixed.</p>
<p>To solve this issue in the most robust and correct way possible requires setting up a couple of contexts and an alias. But before I go through that process I want to talk about Chasm Traps, and I&#8217;m out of time for today. <img src='http://www.dagira.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h3>But Do I Have a Fan Trap?</h3>
<p>I will conclude this post by answering the question I started with. You have a fan trap if you:</p>
<ul>
<li>Have two (or more) tables in a one-many chain of joins</li>
<li>Have measure objects at more than one level</li>
</ul>
<p>You can solve a fan trap with a single checkbox if you have only measure objects from your detail table(s). Otherwise you will get inflated values, confused users, and irritated management.</p>
<p><strong>Related Links</strong></p>
<ul>
<li>Blog Post: <a href="http://www.dagira.com/2007/08/03/designer-sql-traps/">Designer SQL Traps</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.dagira.com/2008/03/03/do-i-have-a-fan-trap/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Designer SQL Traps</title>
		<link>http://www.dagira.com/2007/08/03/designer-sql-traps/</link>
		<comments>http://www.dagira.com/2007/08/03/designer-sql-traps/#comments</comments>
		<pubDate>Fri, 03 Aug 2007 14:06:04 +0000</pubDate>
		<dc:creator>Dave Rathbun</dc:creator>
				<category><![CDATA[Fan / Chasm Trap]]></category>
		<category><![CDATA[Universe Design]]></category>

		<guid isPermaLink="false">http://www.dagira.com/2007/08/03/designer-sql-traps/</guid>
		<description><![CDATA[Designer is one of my favorite parts of the Business Objects product suite. I enjoy creating universes and solving the challenges that occur during that process. If you have worked with Designer yourself then you probably know that there are several different types of challenges that occur fairly frequently&#8230; so frequently, in fact, that we [...]]]></description>
			<content:encoded><![CDATA[<p>Designer is one of my favorite parts of the Business Objects product suite. I enjoy creating universes and solving the challenges that occur during that process. If you have worked with Designer yourself then you probably know that there are several different types of challenges that occur fairly frequently&#8230; so frequently, in fact, that we have names for them. They are Chasm Traps and Fan Traps. I plan to describe each of those traps in this post. I will provide various different solutions (some standard, some not so much) for each in future blog posts.</p>
<p><span id="more-17"></span></p>
<h3>What is a Chasm Trap</h3>
<p>Simply put: A chasm occurs when a series of joins crosses a many &gt;- one -&lt; many relationship. For example:</p>
<p><code>A &gt;- B -&lt; C</code></p>
<p>If I were to write a query that spanned all three of those tables the data from table A and C would be duplicated and measure values would be inflated. The inflation factor can be determined by counting the number of rows from the left that match a particular key and multiplying by the number of rows on the right. For example, a chasm with 3 rows from the left and 2 rows from the right will have 6 total result rows. Any measures taken from this set of data will be inflated. Table A rows will be doubled (from the 2 rows in table C) and table C rows will be tripled (due to the 3 rows from table A).</p>
<p>If you&#8217;re having trouble visualizing this at the moment, don&#8217;t worry. I will have some specific data to talk about when I provide solutions to this issue.</p>
<h3>What is a Fan Trap?</h3>
<p>Again, to put this simply: A fan trap occurs when joins &#8220;fan out&#8221; over multiple one -&lt; many relationships in a row. For example:</p>
<p><code>A -&lt; B -&lt; C</code></p>
<p>A fan trap is not quite as severe as a chasm trap. In fact there are many fan traps that can occur in a universe design that can be ignored as long as you control which types of objects you use. However, if you are not careful then it is possible to return inflated measure values from a fan trap just like in a chasm trap. </p>
<p>How do you recognize these situations? How do you fix them? Stay tuned, as I plan to cover each trap in detail along with various solutions in coming blog posts.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dagira.com/2007/08/03/designer-sql-traps/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>
