<?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; Universe Contexts</title>
	<atom:link href="http://www.dagira.com/category/design/universe-contexts/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>Wed, 01 Feb 2012 17:26:45 +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>Time Sliced Measures Part III: Making Measures</title>
		<link>http://www.dagira.com/2009/12/17/time-sliced-measures-part-iii-making-measures/</link>
		<comments>http://www.dagira.com/2009/12/17/time-sliced-measures-part-iii-making-measures/#comments</comments>
		<pubDate>Fri, 18 Dec 2009 03:52:29 +0000</pubDate>
		<dc:creator>Dave Rathbun</dc:creator>
				<category><![CDATA[2008 GBN - Dallas]]></category>
		<category><![CDATA[Universe Contexts]]></category>
		<category><![CDATA[Universe Design]]></category>

		<guid isPermaLink="false">http://www.dagira.com/?p=187</guid>
		<description><![CDATA[In the first post in this series I defined what time-sliced measures are and why they can be useful in a universe. In the second post I described a special calendar table that was designed and built to support the requirements for this solution. I also showed how the join logic worked in conjunction with [...]]]></description>
			<content:encoded><![CDATA[<p>In the <a href="http://www.dagira.com/2009/08/08/time-sliced-measures-part-i-defining-the-problem/">first post in this series</a> I defined what time-sliced measures are and why they can be useful in a universe. In the <a href="http://www.dagira.com/2009/08/28/time-sliced-measures-part-ii-time-slice-calendar-table/">second post</a> I described a special calendar table that was designed and built to support the requirements for this solution. I also showed how the join logic worked in conjunction with the table design. This post completes the implementation. I am finally going to work on the measure objects that a user will see. </p>
<p>In any universe design project I strive for the following goals:</p>
<ul>
<li><strong>Deliver the correct result</strong><br />
In my opinion, this is always the number one goal in any universe design.</li>
<li><strong>User friendly</strong><br />
This is quite important but secondary to correctness</li>
<li><strong>Easy to maintain</strong><br />
Universe maintenance is always allowed to suffer in order to provide the first two attributes on this list, but it is a worthwhile goal to strive for nonetheless</li>
</ul>
<p>In this post I will show how all three of these goals are ultimately met by this implementation. When I am done I will have a completed universe. <em>This post will cover slides 26 through 30 from my 2008 GBN Conference presentation. There is a link to download the file at the end of this post.</em> <span id="more-187"></span></p>
<h3>A Brief Recap</h3>
<p>The overall goals of this project were listed in the prior posts in this series. The most important ones for this post are:</p>
<ul>
<li>Each report is expected to have multiple time-sliced measures</li>
<li>The process of splitting each time-slice time period into its own SQL statement should be completely transparent</li>
</ul>
<p>Current Year and Prior Year are different time slice attributes. Every report is expected to have month-to-date and year-to-date measures that cover both the current and the prior year. That means I expect to see four different measures used in each document. The month and year date ranges are obviously different, as are the current and prior year ranges. In the last post on this topic I described a special time-slice calendar table and set up different aliases for each required time-slice. I set up contexts to keep queries from hitting more than one time-slice at the same time.</p>
<p>That&#8217;s how we got here. Where to next? It&#8217;s time to build some measures.</p>
<h3>Bits and Pieces</h3>
<p>I subscribe to the thought that anything that makes the universe designer&#8217;s job easier while making the user&#8217;s life harder is the wrong approach. However, if I can do something to make my life easier without impacting the user, then whatever I come up with is fair game. <img src='http://www.dagira.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  That&#8217;s how I arrived at the strategy that I am going to outline next.</p>
<p>Normally a &#8220;bit&#8221; is either a one or a zero. Many of the bit objects used in this solution will be just that. However, I am also going to create some special measure bits that make use of the @Select() function. As a general rule I am not in favor of using this function, but in this case I will and I will justify why in a bit. (heh, pun <img src='http://www.dagira.com/wp-includes/images/smilies/icon_razz.gif' alt=':-P' class='wp-smiley' />  )</p>
<p>I am going to focus on creating time-sliced objects for the revenue object. In order to do this, I am going to create a measure bit called &#8220;Revenue&#8221; that contains only the table / columns required to calculate this value. I am <strong>not going to include an aggregation function for this measure</strong> which violates another one of my universe design rules. Again, I will justify why. The other bit objects will be used to select (or mark) which context is used for each time slice.</p>
<h3>Using Measure Bits</h3>
<p>In my time-sliced solution everything is made up of combinations. Imagine a cartesian product between measures and time periods, something like this:</p>
<p><img src="/tips/time_slice_part_iii/cartesian_measures.jpg" /></p>
<p>Each time-slice on the left is combined with each measure on the right. Rather than create six different references to the revenue formula shown here&#8230;</p>
<p><code>INVOICE_LINE.DAYS * INVOICE_LINE.NB_GUESTS * SERVICE.PRICE</code></p>
<p>&#8230;I am going to create just one. Notice that the code shown above does not have an aggregate function? This is by design&#8230; I am going to use the @Select() function to build my visible measure objects. Here&#8217;s the initial part of the object definition for the CY MTD Revenue object.</p>
<p><code>sum(@Select(Measure Bits\Revenue))</code></p>
<p>By leaving the aggregate function out of the source measure I can also create a minimum, maximum, or other aggregate version of the sales revenue. This is because the code referenced by the @Select() doesn&#8217;t have an aggregate&#8230; and why is this important? Because I <strong>can&#8217;t nest aggregate functions</strong>. If my source measure included the sum() function then that&#8217;s all I can do with it. By keeping it generic (no aggregate) I can reuse it with any aggregate function as needed. So that&#8217;s why I am breaking the rule that says every measure must have an aggregate function.</p>
<p>Ultimately the measure bits are going to be hidden from view so they will never be viewable / usable by report writers. They are only used as building blocks in the Designer application.</p>
<h3>Time Slice Bits</h3>
<p>Now I need to build some time-sliced bits. These are really simple. Here&#8217;s what the object definition looks like for the CY MTD bit object.</p>
<p><img src="/tips/time_slice_part_iii/time_bit_definition.jpg" /></p>
<p>The select clause contains the number 1 and that&#8217;s it. Notice what the help text says? In big CAPITAL letters it says &#8220;DON&#8217;T FORGET THE TABLE!!!&#8221; I wonder what that means? <img src='http://www.dagira.com/wp-includes/images/smilies/icon_lol.gif' alt=':lol:' class='wp-smiley' /> </p>
<p>Here&#8217;s what it means. The 1 is just a placeholder to put something in the Select clause. The Where clause is empty. The From clause comes from the table list, and here&#8217;s what that looks like.</p>
<p><img src="/tips/time_slice_part_iii/table_reference.jpg" /></p>
<p>Stick with me just a little bit longer and this will all make sense. <img src='http://www.dagira.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  Remember that in the earlier posts I set up aliases for my time-slice calendar table. Each alias became part of its own context. A context is a series of joins that make up a particular path through a universe. What I am working towards is a set of time-sliced objects that a user can drag onto their query panel without having to worry about where they come from or how they&#8217;re put together. Here&#8217;s what my schema looks like as a reminder. All of the aliases are on the right side.</p>
<p><img src="/tips/time_slice_part_iii/schema.jpg" /></p>
<p>This structure gives me a way to automatically split out each time-sliced measure into its own path so that a user can combine CY MTD and PY MTD and any of the other options onto one query and run it.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dagira.com/2009/12/17/time-sliced-measures-part-iii-making-measures/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Use Contexts, Dammit</title>
		<link>http://www.dagira.com/2009/09/18/use-contexts-dammit/</link>
		<comments>http://www.dagira.com/2009/09/18/use-contexts-dammit/#comments</comments>
		<pubDate>Fri, 18 Sep 2009 12:27:58 +0000</pubDate>
		<dc:creator>Dave Rathbun</dc:creator>
				<category><![CDATA[Rants]]></category>
		<category><![CDATA[Universe Contexts]]></category>
		<category><![CDATA[Universe Design]]></category>

		<guid isPermaLink="false">http://www.dagira.com/?p=192</guid>
		<description><![CDATA[I haven&#8217;t had a good rant in a while. I&#8217;m overdue.
Here are some real comments that were posted on BOB.
I already have around 18 contexts in Universe and hence I dont want to add any extra 
The last two companies I have worked at, forbade the use of contexts
I only create contexts when I&#8217;ve got [...]]]></description>
			<content:encoded><![CDATA[<p>I haven&#8217;t had a good rant in a while. I&#8217;m overdue.</p>
<p>Here are some real comments that were posted on <a href="http://busobj.forumtopics.com">BOB</a>.</p>
<blockquote><p>I already have around 18 contexts in Universe and hence I dont want to add any extra </p></blockquote>
<blockquote><p>The last two companies I have worked at, forbade the use of contexts</p></blockquote>
<blockquote><p>I only create contexts when I&#8217;ve got no other choice. </p></blockquote>
<p>And this one wins the prize:</p>
<blockquote><p>Here&#8217;s a list of what I cannot do (client requirements) </p>
<p>1. Cannot use contexts in the universe.<br />
&#8230;</p></blockquote>
<p>If you recognize one of your comments, please understand I am not ranting about you as a person, but about the sentiment or opinions expressed in the comment itself. </p>
<p>As a consultant, my job was sometimes to deliver a solution. At other times my job was to provide advice. My advice was based on my assessment of two things: what the client told me they wanted, and what I felt like they really needed. <img src='http://www.dagira.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  <span id="more-192"></span> As a worst-case scenario I was always prepared to walk away from a job rather than work under rules and restrictions that I knew were incorrect and that would prevent me from delivering the proper solution.</p>
<p>So there is really nothing more frustrating to me than to see comments like what I posted above. If I had a client tell me that I could not use contexts, then my job was to find out why they had that opinion, and then do my best to educate them. Sometimes it was because of a bad experience. Sometimes it was because of a lack of proper understanding of what contexts were supposed to be used for. When building a universe, the number one goal should always be to deliver the correct result. Speed and ease of use are secondary. Contexts are frequently a critical component of a successful universe.</p>
<p>So to the next person who gets a job where the client says to them, &#8220;You cannot use contexts,&#8221; here is my advice: first try to educate the client as to the proper use of contexts. If that fails, walk away, and take another job. To a client who has a consultant tell them, &#8220;You really don&#8217;t want to use contexts, they&#8217;re much too complicated,&#8221; here is my advice: hire another consultant. As a client you&#8217;re under no obligation to educate the consultant. <img src='http://www.dagira.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Contexts have a purpose. They&#8217;re not a necessary evil, they&#8217;re just necessary.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dagira.com/2009/09/18/use-contexts-dammit/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Time-Sliced Measures Part II: Time Slice Calendar Table</title>
		<link>http://www.dagira.com/2009/08/28/time-sliced-measures-part-ii-time-slice-calendar-table/</link>
		<comments>http://www.dagira.com/2009/08/28/time-sliced-measures-part-ii-time-slice-calendar-table/#comments</comments>
		<pubDate>Fri, 28 Aug 2009 11:51:03 +0000</pubDate>
		<dc:creator>Dave Rathbun</dc:creator>
				<category><![CDATA[2008 GBN - Dallas]]></category>
		<category><![CDATA[Universe Contexts]]></category>
		<category><![CDATA[Universe Design]]></category>

		<guid isPermaLink="false">http://www.dagira.com/?p=166</guid>
		<description><![CDATA[In the first post in this series I defined what time-sliced measures are and why they can be useful in a universe. I also shared the design requirements for a particular project I was on. The requirements included:

Each report is expected to have multiple time-sliced measures
Users must be able to select the type of calendar [...]]]></description>
			<content:encoded><![CDATA[<p>In the <a href="http://www.dagira.com/2009/08/08/time-sliced-measures-part-i-defining-the-problem/">first post in this series</a> I defined what time-sliced measures are and why they can be useful in a universe. I also shared the design requirements for a particular project I was on. The requirements included:</p>
<ul>
<li>Each report is expected to have multiple time-sliced measures</li>
<li>Users must be able to select the type of calendar during the refresh process; calendar types include Monthly and Fiscal</li>
<li>Users can provide any possible date as the &#8220;to date&#8221; for the time slices</li>
<li>The process of splitting each time-slice time period into its own SQL statement should be completely transparent</li>
<li>The resulting SQL should be as efficient as possible</li>
</ul>
<p>In this post I am going to cover the design of a special table that we built in order to support our solution for these requirements. After I talk about the table design I will cover how I use it in the universe, as well as provide a few pros and cons about this solution as I have outlined it so far. Just to prepare you, this post is a bit longer than most that I write, and gets fairly detailed. <em>This post will cover slides 23 through 25 from my 2008 GBN Conference presentation. There is a link to download the file at the end of this post. </em> <span id="more-166"></span></p>
<h3>Time Slice Calendar Table Definition</h3>
<p>Each time slice has a start date and an end date. The actual dates will change based on whether I am looking at a fiscal quarter or a calendar quarter. I need to be able to provide any reference date as my &#8220;to date&#8221; or input date for each time slice. Finally, I want to be able to compare the current year values with the matching prior year values. All of these requirements can be solved with the following table structure:</p>
<table class="blogtable">
<tr>
<th>Column Name</th>
<th>Description</th>
</tr>
<tr class="alt">
<td>ref_cal_dt</td>
<td>Calendar date used as input for prompts</td>
</tr>
<tr>
<td>cal_tmslc_mn_val</td>
<td>Time slice name</td>
</tr>
<tr class="alt">
<td>cal_nm</td>
<td>Calendar name</td>
</tr>
<tr>
<td>curr_yr_tmslc_strt_dt</td>
<td>Current year date range start date</td>
</tr>
<tr class="alt">
<td>curr_yr_tmslc_end_dt</td>
<td>Current year date range end date</td>
</tr>
<tr>
<td>prior_yr_tmslc_strt_dt</td>
<td>Prior year date range start date</td>
</tr>
<tr class="alt">
<td>prior_yr_tmslc_end_dt</td>
<td>Prior year date range end date</td>
</tr>
</table>
<p>The <code>ref_cal_dt</code> is the reference calendar date. Every time I use this table I need to provide that date, either via a prompt or condition of some kind. <em>If you don&#8217;t need the flexibility of redefining the &#8220;to date&#8221; value in your environment this can be removed.</em> The next two columns are codes for the time slice and calendar type. The last four columns contain the starting and ending dates for each time slice; the first two for the current year and the last two are the matching dates for the prior year. I will talk about each of these columns in a bit more detail in the following paragraphs. I am going to save the reference date for last.</p>
<p>The <code>cal_tmslc_mn_val</code> contains values like MTD, QTD, YTD, FM, FQ, and FY. Each of these codes represents a time slice. For example, QTD is Quarter To Date and FQ is Full Quarter. The type of quarter (monthly or fiscal) is determined by the next column.</p>
<p>The <code>cal_nm</code> or Calendar Name column is used to differentiate between the different types of calendars stored in the table. For our implementation we had two calendars, but there is nothing that says I could not create more if needed. I had to create fiscal time slices and calendar type slices to solve my requirement, and the names became <strong>Month Calendar</strong> and <strong>Period Calendar</strong>. I was asked at one point why we stored the full text representation rather than a code. If my memory is correct, we configured this column as a <strong>compressed character</strong> column in Teradata. Since there are only two values, the compression algorithm was very effective.</p>
<p>Here is some sample data from my table. I mentioned earlier that in order to use this table I have to provide an input or &#8220;reference&#8221; date. For the sample data shown below, the reference date was August 15, 2008. The resulting rows show the start date and end date for all of the available time slices for each calendar type (Month or Period). Both the current year (CY) and prior year (PY) date ranges are retrieved on the same row.</p>
<table class="blogtable">
<tr>
<th>Code</th>
<th>Calendar</th>
<th>CY Start Date</th>
<th>CY End Date</th>
<th>PY Start Date</th>
<th>PY End Date</th>
</tr>
<tr class="alt">
<td>MTD</td>
<td>Month Calendar</td>
<td>8/1/2008</td>
<td>8/15/2008</td>
<td>8/1/2007</td>
<td>8/15/2007</td>
</tr>
<tr>
<td>QTD</td>
<td>Month Calendar</td>
<td>7/1/2008</td>
<td>8/15/2008</td>
<td>7/1/2007</td>
<td>8/15/2007</td>
</tr>
<tr class="alt">
<td>YTD</td>
<td>Month Calendar</td>
<td>1/1/2008</td>
<td>8/15/2008</td>
<td>1/1/2007</td>
<td>8/15/2007</td>
</tr>
<tr>
<td>FM</td>
<td>Month Calendar</td>
<td>8/1/2008</td>
<td>8/31/2008</td>
<td>8/1/2007</td>
<td>8/31/2007</td>
</tr>
<tr class="alt">
<td>FQ</td>
<td>Month Calendar</td>
<td>7/1/2008</td>
<td>9/30/2008</td>
<td>7/1/2007</td>
<td>9/30/2007</td>
</tr>
<tr>
<td>FY</td>
<td>Month Calendar</td>
<td>1/1/2008</td>
<td>12/31/2008</td>
<td>1/1/2007</td>
<td>12/31/2007</td>
</tr>
<tr class="alt">
<td>MTD</td>
<td>Period Calendar</td>
<td>8/10/2008</td>
<td>8/15/2008</td>
<td>8/12/2007</td>
<td>8/17/2007</td>
</tr>
<tr>
<td>QTD</td>
<td>Period Calendar</td>
<td>6/15/2008</td>
<td>8/15/2008</td>
<td>6/17/2007</td>
<td>8/17/2007</td>
</tr>
<tr class="alt">
<td>YTD</td>
<td>Period Calendar</td>
<td>12/30/2007</td>
<td>8/15/2008</td>
<td>12/31/2006</td>
<td>8/17/2007</td>
</tr>
<tr>
<td>FM</td>
<td>Period Calendar</td>
<td>8/10/2008</td>
<td>9/6/2008</td>
<td>8/12/2007</td>
<td>9/8/2007</td>
</tr>
<tr class="alt">
<td>FQ</td>
<td>Period Calendar</td>
<td>6/15/2008</td>
<td>9/6/2008</td>
<td>6/17/2007</td>
<td>9/8/2007</td>
</tr>
<tr>
<td>FY</td>
<td>Period Calendar</td>
<td>12/30/2007</td>
<td>12/27/2008</td>
<td>12/31/2006</td>
<td>12/29/2007</td>
</tr>
</table>
<p>What does this tell me? I see that for August 15, 2008, using the <strong>Month Calendar</strong>, the month to date (MTD) range starts on 8/1/2008 <em>(all dates in this blog post are in MM/DD/YYYY format)</em> and ends on 8/15/2008. The full month starts on 8/1/2008 and runs until 8/31/2008. If I switch to the <strong>Period Calendar</strong> instead, I see that the MTD range runs from 8/10/2008 to 8/15/2008, and the full month (fiscal month rather than calendar month at this point) runs from 8/10/2008 to 9/6/2008.</p>
<p>Now, about that reference date&#8230; in our requirements we had to allow the user to redefine the &#8220;to date&#8221; for any time slice. It is fairly standard for the &#8220;to date&#8221; to be the last warehouse refresh date. Since we had to be able to run any report for any &#8220;to date&#8221; our table starts with the reference date. In the sample data posted above, the reference date was always 8/15/2008. I would see another set of rows for 8/16/2008, for 8/17/2008, for 8/18/2008, and so on. Every single possible date value was stored in the time slice table, and the starting / ending date ranges for all time slices and calendar types were computed and stored for each one.</p>
<p>There is one important note about performance that is appropriate at this point. Because we had to be able to roll values up by multiple calendars, we were required to store all of our data at a daily grain in our fact table. Since weeks do not fall on month boundaries, and since fiscal and monthly calendars do not share the same date ranges, the only possible way to solve the issue was to leave things at the daily grain. As you can imagine, this caused some challenges with query performance.</p>
<h3>Join Fact Table to Time Slice Table</h3>
<p>Now that I have thoroughly explained my special calendar table and its contents, how am I going to use it? This table is going to be the &#8220;driver&#8221; for my time-sliced measures, and drivers need roads. <em>(That is, unless you have a <a href="http://www.imdb.com/title/tt0088763/quotes">nuclear powered DeLorean</a>. <img src='http://www.dagira.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  )</em> I&#8217;ve posted before about contexts being paths or routes through a universe, and that&#8217;s what I need here too. But with only one calendar table and one fact table, where will I get different roads? First I need aliases.</p>
<p>I will create an alias of my special calendar table for each time slice definition. That means since I have six time slices (MTD, QTD, YTD, FM, FQ, and FY) and two years (Current Year CY and Prior Year PY) I need to create 12 aliases. After I do that, I create joins from each of these aliases to my fact table. Normally having multiple dimensions per fact is going to be fine, but in this case I want to ensure that every different time slice forces a separate SQL path&#8230; and now I&#8217;m back to where I need to create the contexts.</p>
<p>Here&#8217;s what a slightly simplified version of the universe looks like. I only created the &#8220;To Date&#8221; slices and left the &#8220;full&#8221; versions out for now.</p>
<p><img src="/tips/time_slice_part_ii/schema.jpg" width="600" height="465" border="0" alt="schema picture" title="Island Resorts Marketing with Time Sliced Calendar table" /></p>
<p>Yes, that is a picture of the venerable Island Resorts Marketing universe, but with some aliases of my time-sliced calendar table added. Each of those aliases is joined to the &#8220;fact&#8221; table called <code>SALES</code>. The original <code>CAL_TIMESLICE</code> table is in the universe in the lower left corner. The six aliases are outlined in red on the right. Each alias has a join that looks like this:</p>
<p><code>SALES.INVOICE_DATE between cy_mtd.CURR_YR_TMSLC_STRT_DT and cy_mtd.CURR_YR_TMSLC_END_DT AND cy_mtd.CAL_TMSLC_MN_VAL = 'MTD' AND cy_mtd.CAL_NM = @Prompt('Please select Calendar Type','A','Time Slice Calendar\Calendar Name',mono,free) and cy_mtd.REF_CAL_DT = @Prompt('Please select Calendar Date','D',,mono,free)</code></p>
<p>I will break this down into steps.</p>
<p>The most direct part of the join takes the invoice date and compares it to the time slice start date and end date, using the <code>BETWEEN</code> operator.</p>
<p><code>SALES.INVOICE_DATE between cy_mtd.CURR_YR_TMSLC_STRT_DT and cy_mtd.CURR_YR_TMSLC_END_DT</code></p>
<p>Next, I want to make sure I get exactly one date range, and that is done first by hard-coding the time slice mnemonic value&#8230;</p>
<p><code>cy_mtd.CAL_TMSLC_MN_VAL = 'MTD'</code></p>
<p>&#8230; and then prompting the user to select the calendar type.</p>
<p><code>cy_mtd.CAL_NM = @Prompt('Please select Calendar Type','A','Time Slice Calendar\Calendar Name',mono,free)</code></p>
<p><em>As an aside, I created a join with a prompt for time-slice code as well. This is a nice enhancement that lets the user pick a single measure for their report and on-the-fly swap it from MTD to QTD or YTD or any other defined time-slice. Of course they can only use one at a time, so that is a limitation of that technique.</em></p>
<p>The final part of the join in my case was a date prompt for the reference date. This is the &#8220;to date&#8221; that I talked about earlier in this post. Please note that there is no LOV for the reference date; I rarely provide a list of values for dates since there is not much value added by that overhead.</p>
<p><code>cy_mtd.REF_CAL_DT = @Prompt('Please select Calendar Date','D',,mono,free)</code></p>
<p>The join logic is the same for every alias except for the hard-coded mnemonic code for time slice. </p>
<h3>Checking Join Structure</h3>
<p>In this scenario as I have built it so far, have I introduced any loops? any fan traps? The answer to both of those questions is &#8220;No, I have not.&#8221; However, I have introduced incompatible joins.</p>
<p>For example, suppose that a user picked a MTD and YTD object at the same time. The SQL (abbreviated here) would include this:</p>
<p><code>cy_mtd.CAL_TMSLC_MN_VAL = 'MTD'<br />
AND cy_mtd.CAL_TMSLC_MN_VAL = 'YTD'</code></p>
<p>This is a problem <img src='http://www.dagira.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  but one that I anticipated. At the beginning of this process I said I wanted to create a way to dynamically and transparently generate separate SQL passes for each time slice. I explained the structure and data for my table, and now I have shown how I join that table to my sales fact. The last step is to isolate each one of these aliases into a separate context. Using my shortcut for <a href="http://www.dagira.com/2008/06/19/how-to-copy-a-context/">copying a universe context</a> this step takes only a few minutes to complete for the initial configuration. Each context includes all of the tables from the original Sales context plus exactly one alias of my special calendar table. Here are the joins for the current year MTD alias:</p>
<p><img src="/tips/time_slice_part_ii/context_joins.jpg" width="600" height="218" border="0" alt="Context joins image" title="Joins for the CY MTD Context" /></p>
<p>And then I create a context for each of the others as well; here is a list of the contexts from my universe at this point:</p>
<p><img src="/tips/time_slice_part_ii/context_list.jpg" width="107" height="127" border="0" alt="Context list image" title="List of joins from my time-slice demo universe" /></p>
<h3>Why This Strategy?</h3>
<p>As I have been sharing this design concept at various conferences or with other universe designers I invariably get questions like &#8220;What made you go this route?&#8221; or &#8220;Why not alias the fact table instead?&#8221; and so on. They are fair questions, and I don&#8217;t have time to answer all of them in this post. <img src='http://www.dagira.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  I will try to quickly point out a few advantages to this technique.</p>
<p>If I alias a fact table I can almost certainly guarantee that I will introduce additional loops in my universe structure. There is a limit to the number of loops that can be detected / displayed by Designer, so adding extra loops when I don&#8217;t have to is not in my best interest. Plus, as blog readers will see soon when I start building objects on this structure, there is a big benefit to having all of my measures come from a single fact.</p>
<p>This technique does not add any new chasm or fan traps to the universe.</p>
<p>This technique allows me to support a potentially infinite number of time slices without doing any date calculations on the fly.</p>
<p>This technique allows me to support a potentially infinite number of calendar types. Here I have shown both fiscal and calendar types, but I could easily add more.</p>
<p>On the negative side, there are complexities associated with creating contexts in the universe. I mentioned above that creating the initial contexts is simple. Any future maintenance will be more complex as a result of all of the contexts in the universe. However, I submit that the complexities of the universe are more than paid for by the advantages to the users who will be creating reports. And whether I chose to alias the fact or the calendar table I would still have this issue so it&#8217;s really a moot point.</p>
<h3>Next Steps</h3>
<p>At this point I have accomplished the following:</p>
<ul>
<li>Created and populated my special calendar table</li>
<li>Created aliases for each time slice / year combination (only &#8220;to date&#8221; versions are shown in this post, but I did create the &#8220;full&#8221; aliases and contexts as well in production)</li>
<li>Created joins that link each time-slice calendar alias to my fact</li>
<li>Created contexts to ensure that each time slice will appear in a separate query pass</li>
</ul>
<p>What&#8217;s next? I have to create some objects so my users can make use of all of my hard work so far. That&#8217;s my next post in this series, which will cover slides 26 through 30 of my talk. Stay tuned. <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>Conference presentation download: <a href="http://www.dagira.com/presentations/2008/2008_GBN_Designer_Essentials.zip">Universe Designer Essentials and Beyond</a></li>
<li>Prior post in this series: <a href="http://www.dagira.com/2009/08/08/time-sliced-measures-part-i-defining-the-problem/">Time-Sliced Measures Part I: Defining the Problem</a></li>
<li>Other supplemental information: <a href="http://www.teradataforum.com/l020829a.htm">Teradata Compression Explained</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.dagira.com/2009/08/28/time-sliced-measures-part-ii-time-slice-calendar-table/feed/</wfw:commentRss>
		<slash:comments>21</slash:comments>
		</item>
		<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>Context Versus Alias Overview</title>
		<link>http://www.dagira.com/2009/07/22/context-versus-alias-overview/</link>
		<comments>http://www.dagira.com/2009/07/22/context-versus-alias-overview/#comments</comments>
		<pubDate>Wed, 22 Jul 2009 14:24:36 +0000</pubDate>
		<dc:creator>Dave Rathbun</dc:creator>
				<category><![CDATA[2008 GBN - Dallas]]></category>
		<category><![CDATA[Universe Contexts]]></category>
		<category><![CDATA[Universe Design]]></category>

		<guid isPermaLink="false">http://www.dagira.com/?p=163</guid>
		<description><![CDATA[In an attempt to complete the blog posts related to my GBN Conference presentation from 2008 before the upcoming conference in 2009 kicks off I bring you Context Versus Alias: The Smackdown Cage Match.   People often post on BOB as if contexts and aliases are competing for the same job, and that is [...]]]></description>
			<content:encoded><![CDATA[<p>In an attempt to complete the blog posts related to my GBN Conference presentation from 2008 before the upcoming conference in 2009 kicks off I bring you Context Versus Alias: The Smackdown Cage Match. <img src='http://www.dagira.com/wp-includes/images/smilies/icon_lol.gif' alt=':lol:' class='wp-smiley' />  People often post on BOB as if contexts and aliases are competing for the same job, and that is certainly not true. Each technique has an appropriate use, and I will cover them (although not in much depth) in this post. I won&#8217;t be showing the process for creating contexts or aliases in this post as it would end up being too long.</p>
<p><em>This post is related to slides 13 through 17 from my <a href="http://www.dagira.com/presentations/2008/2008_GBN_Designer_Essentials.zip">2008 conference presentation</a>.</em> <span id="more-163"></span></p>
<h3>What is an Alias?</h3>
<p>The alias technique has been around far longer than Business Objects has. Whenever a SQL script needs to access the same table more than once an alias is used. One of the easiest examples is an employee table that contains a key to the employee&#8217;s manager. In order to return a list of employees and who they work for I might write SQL code something like this:</p>
<p><code>SELECT emp.name<br />
, mgr.name<br />
FROM employees emp<br />
, employees mgr<br />
WHERE emp.mgr_id = mgr.emp_id</code></p>
<p>There is only one table in the code: the <code>employees</code> table. However, in order to get the employee name <strong>and</strong> the manager name, I need to join the table back to itself. In order to accomplish that, I have to give each side of the relationship a unique name. That is the SQL alias for each table, and the same technique is used in building universes.</p>
<p>Aliases are more typical in a universe environment with lookup tables. For example, in the screen shot shown below (taken from my presentation) the <code>COUNTRY</code> table has two unique purposes. In one case it is used to show where a Resort is located. In the other case it contains the Region for each customer. An alias is indicated by the fact that the <code>COUNTRY</code> table is always on the &#8220;one&#8221; side of a one-to-many join. This issue (and solution) can be found in the Island Resorts universe.</p>
<p><img src="/tips/alias_vs_context/country_joins.jpg" width="494" height="105" border="0" alt="country join example" title="Country joins showing two purposes for the table" /></p>
<p>To summarize so far: an alias is used when the same table is used more than once, and is typically indicated by that table always being on the &#8220;one&#8221; side of a one-to-many join.</p>
<h3>What is a Context?</h3>
<p>A context, on the other hand, is a concept that probably originated within a universe. If a SQL developer decides that he or she needs two scripts to get the job done, then that&#8217;s what they write. But a universe is supposed to be able to generate SQL for a non-developer. So how can it have the intelligence to know when to split something into multiple SQL passes? That is the role of a context.</p>
<p>Here is another screen shot borrowed from my presentation.</p>
<p><img src="/tips/alias_vs_context/context_paths.jpg" width="481" height="268" border="0" alt="context path example" title="Reservations and Sales Contexts example" /></p>
<p>In the diagram shown above, the two end points are <code>CUSTOMER</code> and <code>SERVICE</code>. There are two ways to figure out which service a customer is related to. The first relationship goes through the reservations tables and is used to show which services a customer has requested. The second relationship goes through the sales tables and is used to bill the customer for services used. These relationships are equally important.</p>
<p>A context is indicated in this case because there is a loop. <em>(Please note, however, that contexts also solve fan and chasm traps which do not involve loops.)</em> A loop in a universe is found when a sequence of joins can be selected that start and end at the same table. In this case, I could map from the <code>CUSTOMER</code> table through the <code>INVOICE_LINE</code> table, the <code>SERVICE</code> table, back through the reservations tables and end up back where I started. That&#8217;s a loop. If the loop is not resolved in some way, Desktop Intelligence and Web Intelligence will issue an &#8220;incompatible combination of objects&#8221; message rather than run the invalid SQL.</p>
<p>An alias was indicated by tables on the &#8220;one&#8221; side of every join. Contexts are indicated by tables appearing only on the &#8220;many&#8221; side of a one-to-many join. In this loop, those are the <code>RESERVATION_LINE</code> and <code>INVOICE_LINE</code> tables. Those tables will ultimately drive my context creation process.</p>
<p>To summarize contexts: they are used to resolve loops (and other SQL traps) and are indicated by tables always appearing on the &#8220;many&#8221; side of a one-to-many join.</p>
<h3>Context Versus Alias</h3>
<p>I have shown examples of where each technique would be appropriate. Is it possible to use an alias to solve a context issue, or a context to solve an alias challenge? To be honest, yes. <img src='http://www.dagira.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  But you would end up creating more problems than you solve. Here&#8217;s a summary of the two features:</p>
<ul>
<li>Alias Features
<ul>
<li>Aliases are simple to create</li>
<li>Objects for each alias can be created, for example Resort Country and Customer Country from my example given above</li>
<li>Once created no further maintenance is required</li>
<li>Aliases eliminate (break) loops</li>
</ul>
</li>
<li>Context Features
<ul>
<li>Contexts are more complex to create</li>
<li>Every join must exist in at least one context; if not, it becomes an <em>isolated join</em></li>
<li>Loops are not eliminated; two (or more) paths are identified and used but the loop remains</li>
<li>Contexts can also resolve <a href="http://www.dagira.com/category/design/fan-chasm-trap/">fan or chasm traps</a></li>
</ul>
</li>
</ul>
<p>I have seen more than one post on <a href="http://busobj.forumtopics.com">BOB</a> where people say things like, &#8220;&#8230; my client doesn&#8217;t allow contexts&#8230;&#8221; or &#8220;&#8230; won&#8217;t use contexts because they are too complicated&#8230;&#8221; and I cringe. You would not use a hammer to put in a screw because a screw-driver is &#8220;too complex&#8221; so why would you use the wrong tool to resolve an issue in a universe? It doesn&#8217;t make sense.</p>
<h3>Conclusion</h3>
<p>Aliases and contexts are not substitutes for each other: each has a unique purpose and a place in universe design. I tried to show that in my brief overview slides in my presentation, and hopefully have added some value by including more detail in this post. I have other posts on contexts and aliases and other universe design issues published, and a few more in draft form that I hope to finish as time allows. The complete presentation can be downloaded from my presentations page, linked below.</p>
<p><strong>Related Links</strong></p>
<ul>
<li><a href="http://www.dagira.com/conference-presentations/">Conference presentations page</a></li>
<li><a href="http://www.dagira.com/presentations/2008/2008_GBN_Designer_Essentials.zip">Universe Designer Essentials and Beyond</a> conference presentation</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.dagira.com/2009/07/22/context-versus-alias-overview/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>What Determines Context Order?</title>
		<link>http://www.dagira.com/2009/01/12/what-determines-context-order/</link>
		<comments>http://www.dagira.com/2009/01/12/what-determines-context-order/#comments</comments>
		<pubDate>Mon, 12 Jan 2009 05:24:13 +0000</pubDate>
		<dc:creator>Dave Rathbun</dc:creator>
				<category><![CDATA[Universe Contexts]]></category>
		<category><![CDATA[Universe Design]]></category>

		<guid isPermaLink="false">http://www.dagira.com/?p=139</guid>
		<description><![CDATA[It might not be obvious, but when you are looking at the &#8220;list mode&#8221; screen in the Universe Designer product there is a method to the madness that is the order of the joins displayed. The joins are &#8211; believe it or not &#8211; displayed in chronological order based on when they were created. This [...]]]></description>
			<content:encoded><![CDATA[<p>It might not be obvious, but when you are looking at the &#8220;list mode&#8221; screen in the Universe Designer product there is a method to the madness that is the order of the joins displayed. The joins are &#8211; believe it or not &#8211; displayed in chronological order based on when they were created. This can help when you have to include a new join in a context as it will always be at the end of the list. I have become used to that feature.</p>
<p>But I have yet to figure out how the contexts are ordered on the same screen. Has anyone ever noticed a pattern as to how the order of contexts is determined? If so, I would love to hear it. <img src='http://www.dagira.com/wp-includes/images/smilies/icon_cool.gif' alt='8-)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.dagira.com/2009/01/12/what-determines-context-order/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>How To Copy a Context</title>
		<link>http://www.dagira.com/2008/06/19/how-to-copy-a-context/</link>
		<comments>http://www.dagira.com/2008/06/19/how-to-copy-a-context/#comments</comments>
		<pubDate>Thu, 19 Jun 2008 13:46:45 +0000</pubDate>
		<dc:creator>Dave Rathbun</dc:creator>
				<category><![CDATA[Universe Contexts]]></category>
		<category><![CDATA[Universe Design]]></category>

		<guid isPermaLink="false">http://www.dagira.com/?p=92</guid>
		<description><![CDATA[Some time back I answered a question on BOB that asked:
How can I copy a context?
There are a number of reasons why you might want to do this. In a semi-complex universe you might have a bunch of snowflake tables and a series of fact tables. After building the first context, the second (third, fourth&#8230;) [...]]]></description>
			<content:encoded><![CDATA[<p>Some time back I answered a question on BOB that asked:</p>
<blockquote><p>How can I copy a context?</p></blockquote>
<p>There are a number of reasons why you might want to do this. In a semi-complex universe you might have a bunch of snowflake tables and a series of fact tables. After building the first context, the second (third, fourth&#8230;) are essentially the same but with a different fact table. As far as I know there is no way to copy / paste a context, but there is a fairly simple way to source a new context from an existing one. Here&#8217;s what I do: <span id="more-92"></span></p>
<ol>
<li>Create the first context</li>
<li>After saving the first context, make sure List Mode is activated (it will be on by default if this is the first context in the universe)</li>
<li>Click (not double-click) the first context to highlight it; this will select all of the joins that you included in that first context</li>
<li>With the CTRL key and your mouse, deselect joins to the first fact and add (select) joins to the second fact; when you are done you will have all of the joins that were created in the first context except for the fact table joins</li>
<li>Click the &#8220;Add Context&#8221; button on the toolbar, or make the equivalent selection from the menu</li>
</ol>
<p>When you&#8217;re done, you will have created a second context based on the first context, even if you cannot copy and paste a context definition. It works very well. <img src='http://www.dagira.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>I have a universe for my current project that has 22 extremely similar contexts. There is only one table that is different from one context to the next, and each context contains a large number of joins. It would have been a real nightmare to try to create each context manually (and I suspect prone to error). Using this technique made the context creation step very easy. <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://www.forumtopics.com/busobj/viewtopic.php?t=87761">Topic on BOB</a> where I originally answered this question</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.dagira.com/2008/06/19/how-to-copy-a-context/feed/</wfw:commentRss>
		<slash:comments>2</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>23</slash:comments>
		</item>
	</channel>
</rss>

