<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://sqlblog.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Louis Davidson : SQL Server, SQL Techniques</title><link>http://sqlblog.com/blogs/louis_davidson/archive/tags/SQL+Server/SQL+Techniques/default.aspx</link><description>Tags: SQL Server, SQL Techniques</description><dc:language>en</dc:language><generator>CommunityServer 2.1 SP2 (Build: 61129.1)</generator><item><title>Quest DMV Breakfast Code – Disk IO</title><link>http://sqlblog.com/blogs/louis_davidson/archive/2009/11/04/quest-dmv-breakfast-code-disk-io.aspx</link><pubDate>Wed, 04 Nov 2009 17:52:43 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:18532</guid><dc:creator>drsql</dc:creator><slash:comments>1</slash:comments><comments>http://sqlblog.com/blogs/louis_davidson/comments/18532.aspx</comments><wfw:commentRss>http://sqlblog.com/blogs/louis_davidson/commentrss.aspx?PostID=18532</wfw:commentRss><wfw:comment>http://sqlblog.com/blogs/louis_davidson/rsscomments.aspx?PostID=18532</wfw:comment><description>For any of you who attended the Quest breakfast at PASS (and anyone else really) I wanted to go ahead and post the code and give a little wrap up/explanation. (I will post the stuff on perf counters later. They are cool, but this is really what I wanted...(&lt;a href="http://sqlblog.com/blogs/louis_davidson/archive/2009/11/04/quest-dmv-breakfast-code-disk-io.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://sqlblog.com/aggbug.aspx?PostID=18532" width="1" height="1"&gt;</description><category domain="http://sqlblog.com/blogs/louis_davidson/archive/tags/SQL+Server/default.aspx">SQL Server</category><category domain="http://sqlblog.com/blogs/louis_davidson/archive/tags/Dynamic+Management/default.aspx">Dynamic Management</category><category domain="http://sqlblog.com/blogs/louis_davidson/archive/tags/SQL+Techniques/default.aspx">SQL Techniques</category><category domain="http://sqlblog.com/blogs/louis_davidson/archive/tags/PASS/default.aspx">PASS</category><category domain="http://sqlblog.com/blogs/louis_davidson/archive/tags/SQL+Tools/default.aspx">SQL Tools</category><category domain="http://sqlblog.com/blogs/louis_davidson/archive/tags/Speaking/default.aspx">Speaking</category></item><item><title>Commenting your code</title><link>http://sqlblog.com/blogs/louis_davidson/archive/2008/07/30/commenting-your-code.aspx</link><pubDate>Thu, 31 Jul 2008 02:19:43 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:8132</guid><dc:creator>drsql</dc:creator><slash:comments>8</slash:comments><comments>http://sqlblog.com/blogs/louis_davidson/comments/8132.aspx</comments><wfw:commentRss>http://sqlblog.com/blogs/louis_davidson/commentrss.aspx?PostID=8132</wfw:commentRss><wfw:comment>http://sqlblog.com/blogs/louis_davidson/rsscomments.aspx?PostID=8132</wfw:comment><description>&lt;p&gt;As I am easing back into real life from writing the book, I am in search of easy targets for blogging.&amp;#160; My boss mentioned &lt;a href="http://www.codinghorror.com/blog/archives/001150.html" target="_blank"&gt;this blog&lt;/a&gt; over on Jeff Atwood's Coding Horror Blog and it got me thinking about commenting.&amp;#160; His advice is to only comment &amp;quot;why&amp;quot; the code works.&amp;#160; I can't quite agree, because the code he claims to be acceptable is:&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="2"&gt;private double SquareRootApproximation(n) {     &lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New" size="2"&gt;&amp;#160; r = n / 2;     &lt;br /&gt;&amp;#160; while ( abs( r - (n/r) ) &amp;gt; t ) {      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; r = 0.5 * ( r + (n/r) );      &lt;br /&gt;&amp;#160; }      &lt;br /&gt;&amp;#160; return r;      &lt;br /&gt;}      &lt;br /&gt;System.out.println( &amp;quot;r = &amp;quot; + SquareRootApproximation(r) );&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;I mean, it is better than some code I have seen,&amp;#160; but still, I would like a bit more information about why this works.&amp;#160; Maybe the name of the algorithm used, or at least what to do if this fails to provide the expected results.&amp;#160; Admittedly this is probably something that could be easily found, but most algorithms are not.&amp;#160; Comments in my mind should at least lead you to understand the mindset of the programmer.&amp;#160; What would actually improve this code in my mind is to change the variables to full words (though in this case it might not make sense to do this.) &lt;/p&gt;  &lt;p&gt;On an extremely different side of things is &lt;a href="http://www.mssqltips.com/tip.asp?tip=1213" target="_blank"&gt;this article&lt;/a&gt; from &amp;quot;&lt;a href="http://www.mssqltips.com/author.asp?authorid=11"&gt;Edgewood Solutions Engineers&lt;/a&gt;&amp;quot; on mssqltips.com. Their answer is to explain what the code is doing in simple terms, making sure to comment almost everything.&amp;#160; They have a very elaborate header devised, with dependencies, both users of the object and objects it used.&amp;#160; Most of what is said seems a bit like overkill, but their point here &amp;quot;Comment all of the major code blocks of the code and the critical minor points that can be easily overlooked such as a obscure WHERE clause.&amp;quot; is a good one.&amp;#160; I generally pepper my code with comments where I think it will be hard to debug for myself later, with a consideration for others, particularly when those others will call me to explain the code.&lt;/p&gt;  &lt;p&gt;Which brings me to my commenting philosophy. I personally think you have to comment to the expected lowest common denominator.&amp;#160; Think of the dumbest person who could have the need to read your code who is also qualified to have their job (otherwise you would have to write instructions on every line of code). If the qualified person can figure out what you are doing just by your naming conventions and , then it doesn't need comments. But if that person would look at the code and reasonable figure it out, then there is no need to comment the code.&amp;#160; What this requires is a few things:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;Naming objects&lt;/strong&gt; - if your procedures, tables, columns, functions all have meaningful names, you won't have to explain what they mean, saving time&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Good design&lt;/strong&gt; - if the relationship between objects and the cardinality of those relationships is clear, then you don't need to explain that what you are doing is hack due to poor thinking...&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Naming variables&lt;/strong&gt; - probably the most important thing to avoid the need for comments is naming stuff.&amp;#160; Name variables with words, not single character values (except sometimes i, x, etc will suffice for obvious typical uses)&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Reasonable code formatting&lt;/strong&gt; - SQL has no real form, so you &lt;em&gt;could&lt;/em&gt; write procedures on a single line.&amp;#160; You could.&amp;#160; You could smash your hand with a hammer too.&amp;#160; Neither action would be very good.&amp;#160; (Consider using Red-Gate's SQL Refactor tool if nothing else.)&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;However, the fact is, for SQL code, the real problem comes in when you start coming up with cool relational methods of solving problems that most moderately qualified people wouldn't get. For example the trick of using a sequence table to break apart a comma delimited list. Couple that with a join and you get some amazingly cool code, but how do you comment it?&lt;/p&gt;  &lt;p&gt;For example, say an architect that shouldn't be an architect designs a table with a comma delimited list like this (didn't I mention good design earlier?&amp;#160; I hate having to say this is a hack, but it is an elegant hack...)&lt;/p&gt;  &lt;p&gt;&lt;em&gt;&lt;font color="#008000"&gt;--excerpted from Chapter 7 of &lt;/font&gt;&lt;/em&gt;&lt;a href="http://www.apress.com/book/view/143020866x" target="_blank"&gt;&lt;em&gt;&lt;font color="#008000"&gt;Pro SQL Server 2008 Relational Database Design and Implementation&lt;/font&gt;&lt;/em&gt;&lt;/a&gt;    &lt;br /&gt;&lt;font face="Courier New" size="2"&gt;CREATE TABLE poorDesign      &lt;br /&gt;(      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; poorDesignId int,      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; badValue varchar(20)      &lt;br /&gt;)&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="2"&gt;INSERT INTO poorDesign --using 2008 syntax     &lt;br /&gt;VALUES (1,'1,3,56,7,3,6'),      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; (2,'22,3'),      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; (3,'1')&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="2"&gt;&lt;/font&gt;You can &amp;quot;normalize&amp;quot; this set using a table of numbers (in my examples named tools.sequence) and a really cool join:&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="2"&gt;SELECT&amp;#160;&amp;#160;&amp;#160; poorDesign.poorDesignId as betterDesignId,     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; SUBSTRING(',' + poorDesign.badValue + ',',i + 1,      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; CHARINDEX(',',',' + poorDesign.badValue + ',',i + 1) - i - 1)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font face="Courier New" size="2"&gt;as betterScalarValue     &lt;br /&gt;FROM&amp;#160;&amp;#160;&amp;#160;&amp;#160; poorDesign      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; JOIN tools.sequence      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; on i &amp;gt;= 1      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; AND i &amp;lt; LEN(',' + poorDesign.badValue + ',') - 1      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; AND SUBSTRING(',' + + poorDesign.badValue + ',', i, 1) = ','&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;But are there enough pixels available on the planet to make that more understandable to most SQL programmers? Even the reasonably qualified?&amp;#160;&amp;#160; I mean, I am still kind of amazed at the technique and the fact that it returns the following:&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" size="2"&gt;betterDesignId betterScalarValue     &lt;br /&gt;-------------- -----------------      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 1&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 1      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 1&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 3      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 1&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 56      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 1&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 7      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 1&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 3      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 1&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 6      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 2&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 22      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 2&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 3      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 3&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 1&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;still impresses me.&amp;#160; Frankly I don't know how to comment that code to make it readable.&amp;#160; In a real situation I would settle for a comment before the SELECT that stated:&lt;/p&gt;  &lt;p&gt;--Uses a table of numbers to parse the comma delimited list into a SQL acceptable format.   &lt;br /&gt;--If you don't understand this code, read this article: &lt;a title="http://www.sommarskog.se/arrays-in-sql-2005.html#tblnum" href="http://www.sommarskog.se/arrays-in-sql-2005.html#tblnum"&gt;http://www.sommarskog.se/arrays-in-sql-2005.html#tblnum&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Opinions? What do you use for a comments in your code?&amp;#160; Do you have commenting policies?&lt;/p&gt;&lt;img src="http://sqlblog.com/aggbug.aspx?PostID=8132" width="1" height="1"&gt;</description><category domain="http://sqlblog.com/blogs/louis_davidson/archive/tags/SQL+Server/default.aspx">SQL Server</category><category domain="http://sqlblog.com/blogs/louis_davidson/archive/tags/Database+Design/default.aspx">Database Design</category><category domain="http://sqlblog.com/blogs/louis_davidson/archive/tags/SQL+Techniques/default.aspx">SQL Techniques</category><category domain="http://sqlblog.com/blogs/louis_davidson/archive/tags/Best+Practices/default.aspx">Best Practices</category></item><item><title>The joys of a calendar table (ytd, month, and quarter summations)</title><link>http://sqlblog.com/blogs/louis_davidson/archive/2006/12/09/the-joys-of-a-calendar-table-ytd-month-and-quarter-summations.aspx</link><pubDate>Sun, 10 Dec 2006 01:13:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:412</guid><dc:creator>drsql</dc:creator><slash:comments>0</slash:comments><comments>http://sqlblog.com/blogs/louis_davidson/comments/412.aspx</comments><wfw:commentRss>http://sqlblog.com/blogs/louis_davidson/commentrss.aspx?PostID=412</wfw:commentRss><wfw:comment>http://sqlblog.com/blogs/louis_davidson/rsscomments.aspx?PostID=412</wfw:comment><description>&lt;P&gt;There was a &lt;A href="http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=994735&amp;amp;SiteID=1" target=_blank&gt;&lt;FONT color=#0066a7&gt;question on the forums&lt;/FONT&gt;&lt;/A&gt; the other day that asked how to get a total for the current month, the current quarter, and year to date.&amp;nbsp; It is actually a pretty easy task when using a calendar table.&amp;nbsp; I have one you can use here (I fixed an error in it that I just found too!): &lt;A href="http://drsql.spaces.live.com/blog/cns!80677FB08B3162E4!1349.entry"&gt;&lt;FONT color=#0066a7&gt;http://drsql.spaces.live.com/blog/cns!80677FB08B3162E4!1349.entry&lt;/FONT&gt;&lt;/A&gt; 
&lt;P&gt;For an example, I will use the SalesOrderHeader and SalesOrderDetail tables from AdventureWorks, and use the LineTotal to do the summations.&amp;nbsp; I will group on the AccountNumber.&amp;nbsp;&amp;nbsp; So the query is: 
&lt;P&gt;&lt;FONT color=#004080&gt;select SalesOrderHeader.AccountNumber,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sum(case when today.year = calendar.year&amp;nbsp; and today.month &amp;gt;= calendar.month &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; then LineTotal else 0 end ) as ytdTotal,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sum(case when today.year = calendar.year&amp;nbsp; and today.quarter = calendar.quarter &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; then LineTotal else 0 end ) as quarterTotal,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sum(case when today.year = calendar.year&amp;nbsp; and today.month = calendar.month&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; then LineTotal else 0 end ) as monthTotal&lt;BR&gt;from&amp;nbsp;&amp;nbsp; sales.SalesOrderHeader&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; join sales.SalesOrderDetail&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; on SalesOrderHeader.SalesOrderId = SalesOrderDetail.SalesOrderId&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; join dbo.calendar&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; on calendar.dateValue = SalesOrderHeader.OrderDate&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; join dbo.calendar as today&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; on today.dateValue =&amp;nbsp;'2001-12-31' --vary this value to vary the&amp;nbsp;date of "today"&lt;BR&gt;group by SalesOrderHeader.AccountNumber&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#004080&gt;So let's briefly build this query from the ground up.&amp;nbsp; First, the&lt;/FONT&gt; base data from the sales schema in adventureworks.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;FONT color=#004080&gt;from&amp;nbsp;&amp;nbsp; sales.SalesOrderHeader&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; join sales.SalesOrderDetail&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; on SalesOrderHeader.SalesOrderId = SalesOrderDetail.SalesOrderId&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Next, join in the calendar table two times:&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#0000a0&gt;from&amp;nbsp;&amp;nbsp; sales.SalesOrderHeader&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; join sales.SalesOrderDetail&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; on SalesOrderHeader.SalesOrderId = SalesOrderDetail.SalesOrderId&lt;BR&gt;&lt;/FONT&gt;&lt;STRONG&gt;&lt;FONT color=#0000a0&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; join dbo.calendar&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; on calendar.dateValue = SalesOrderHeader.OrderDate&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; join dbo.calendar as today&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; on today.dateValue = '2001-12-31'&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;The first calendar will associate one row in the calendar table with each row being output.&amp;nbsp; The cardinality of the set will not be changed because the calendar has one row per day.&amp;nbsp; The second copy of the calendar table I aliased today because it will usually represent the current day (it could be anything).&amp;nbsp; What this does is add another copy of the calendar table, giving you all of the columns of that date to do math with (if you don't see that, it will be more clear in a moment (I hope :)&lt;/P&gt;
&lt;P&gt;Next comes the column that will be grouped by.&amp;nbsp; In this case I am using the account number.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;&lt;FONT color=#004080&gt;&lt;STRONG&gt;select SalesOrderHeader.AccountNumber&lt;BR&gt;&lt;/STRONG&gt;from&amp;nbsp;&amp;nbsp; sales.SalesOrderHeader&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; join sales.SalesOrderDetail&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; on SalesOrderHeader.SalesOrderId = SalesOrderDetail.SalesOrderId&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; join dbo.calendar&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; on calendar.dateValue = SalesOrderHeader.OrderDate&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; join dbo.calendar as today&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; on today.dateValue = '2001-12-31'&lt;BR&gt;&lt;STRONG&gt;group by SalesOrderHeader.AccountNumber&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;This makes the set now one row per account number, with a "table" of values associated to each account number that we can use aggregates on.&amp;nbsp; This is where the interesting stuff begins (you were hoping, weren't you!):&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#004080&gt;select SalesOrderHeader.AccountNumber,&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#004080&gt;&lt;STRONG&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sum(case when today.year = calendar.year&amp;nbsp; and today.month &amp;gt;= calendar.month &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; then LineTotal else 0 end ) as ytdTotal,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sum(case when today.year = calendar.year&amp;nbsp; and today.quarter = calendar.quarter &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; then LineTotal else 0 end ) as quarterTotal,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sum(case when today.year = calendar.year&amp;nbsp; and today.month = calendar.month&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; then LineTotal else 0 end ) as monthTotal&lt;BR&gt;&lt;/STRONG&gt;from&amp;nbsp;&amp;nbsp; sales.SalesOrderHeader&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; join sales.SalesOrderDetail&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; on SalesOrderHeader.SalesOrderId = SalesOrderDetail.SalesOrderId&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; join dbo.calendar&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; on calendar.dateValue = SalesOrderHeader.OrderDate&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; join dbo.calendar as today&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; on today.dateValue = '2001-12-31'&lt;BR&gt;group by SalesOrderHeader.AccountNumber&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;Because each one of these tables for aggregates has calendar table rows associated with the date or order, and the "current" date, you can use this fact to pick out values you are interested in for a given sum.&amp;nbsp; take the ytdTotal one:&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#004080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sum(case when today.year = calendar.year&amp;nbsp; and today.month &amp;gt;= calendar.month &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; then LineTotal else 0 end ) as ytdTotal,&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;For each row I check the year of the order, and see if it matches the year we are looking for.&amp;nbsp; Then check to see if the order month is less than or equal to the current month.&amp;nbsp; If it is, put out the LineTotal, else just use 0.&amp;nbsp; You can build very powerful expressions that are extremely fast by varying the way you compare the current day to the date of the order.&amp;nbsp; In an &lt;A href="http://drsql.spaces.live.com/blog/cns!80677FB08B3162E4!1297.entry" target=_blank&gt;&lt;FONT color=#0066a7&gt;earlier article&lt;/FONT&gt;&lt;/A&gt;, I also showed how you could use relative positions in the calendar table to get the past 6 months, past 13 months, etc, without any kind of ugly math.&amp;nbsp;For this example, if you wanted to get the past&amp;nbsp;6 months, you could simply add:&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#004080&gt;sum(case when today.relativeMonthCount -5&amp;nbsp;&amp;lt;= calendar.relativeMonthCount&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; and today.relativeMonthCount &amp;gt;= calendar.relativeMonthCount&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;then LineTotal else 0 end ) as past6MonthsTotal&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;Getting the equation just right can be a bit tricky (at least for my brain :), so I generally test my date ranges using a query like this:&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#004080&gt;select distinct calendar.year, calendar.month&lt;BR&gt;from dbo.calendar&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; join dbo.calendar as today &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; on today.dateValue = '2001-12-31' &lt;BR&gt;where&amp;nbsp;today.relativeMonthCount -5 &amp;lt;= calendar.relativeMonthCount &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; and today.relativeMonthCount &amp;gt;= calendar.relativeMonthCount&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;Which returns:&lt;/P&gt;
&lt;P&gt;year&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; month&lt;BR&gt;-------- --------&lt;BR&gt;2001&amp;nbsp;&amp;nbsp;&amp;nbsp; 7&lt;BR&gt;2001&amp;nbsp;&amp;nbsp;&amp;nbsp; 8&lt;BR&gt;2001&amp;nbsp;&amp;nbsp;&amp;nbsp; 9&lt;BR&gt;2001&amp;nbsp;&amp;nbsp;&amp;nbsp; 10&lt;BR&gt;2001&amp;nbsp;&amp;nbsp;&amp;nbsp; 11&lt;BR&gt;2001&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;12&lt;/P&gt;
&lt;P&gt;Crossposted to &lt;A href="http://s"&gt;&lt;FONT color=#0066a7&gt;&lt;A href="http://drsql.spaces.live.com"&gt;http://&lt;/FONT&gt;&lt;/A&gt;drsql.spaces.live.com&lt;/A&gt; &lt;/P&gt;&lt;img src="http://sqlblog.com/aggbug.aspx?PostID=412" width="1" height="1"&gt;</description><category domain="http://sqlblog.com/blogs/louis_davidson/archive/tags/SQL+Server/default.aspx">SQL Server</category><category domain="http://sqlblog.com/blogs/louis_davidson/archive/tags/T-SQL/default.aspx">T-SQL</category><category domain="http://sqlblog.com/blogs/louis_davidson/archive/tags/SQL+Techniques/default.aspx">SQL Techniques</category></item></channel></rss>