|
|
|
Valued Member
      
Group: General Forum Members
Last Login: Wednesday, June 12, 2013 3:29 AM
Points: 53,
Visits: 240
|
|
hugo-939487 (11/15/2010)
Another variaton, using the MONTH function: SELECT [Month] = DATENAME(mm,SomeDateTime), Amount = SUM(SomeAmount) FROM #MyHead WHERE SomeDateTime >= '2010' AND SomeDateTime < '2011' GROUP BY DATENAME(mm,SomeDateTime), MONTH(SomeDateTime) ORDER BY MONTH(SomeDateTime) ;
This is the best one, I think. Adding MONTH function won't change the grouping as it's the same and it will still use seek. You can also use DATEPART(mm, SomeDate).
|
|
|
|
|
Ten Centuries
      
Group: General Forum Members
Last Login: Yesterday @ 5:42 PM
Points: 1,380,
Visits: 2,637
|
|
Ola L Martins-329921 (11/15/2010) Maybe the low ratings is due to the fact that most programmers and db-developers "know" this solution already: The old "sort numbers stored as text as numbers"... ("1" ,"2"..."10", "11" and NOT "1", "10", "11", "2", "3"...).
I like the technique, but you should clarify "any year" is not actually any year, it is a valid year within the sql server time span...
I agree with you that most programmers and db-developers should already know this. Also as Jeff wrote in his article this is something that when possible should be handled by the application. However this article was requested because it keeps coming up as a question in the forums. Also remember that a lot of the people who visit these forums may not be as advanced as you.
Jeff, great "Spackle" article. Thanks.
--------------------------------------------------------------------- Use Full Links: KB Article from Microsoft on how to ask a question on a Forum
|
|
|
|
|
SSChampion
        
Group: General Forum Members
Last Login: Yesterday @ 9:49 AM
Points: 13,436,
Visits: 25,281
|
|
|
|
|
|
SSC-Addicted
      
Group: General Forum Members
Last Login: Tuesday, June 11, 2013 10:25 AM
Points: 485,
Visits: 1,569
|
|
Kristian Ask (11/15/2010)
hugo-939487 (11/15/2010)
Another variaton, using the MONTH function: SELECT [Month] = DATENAME(mm,SomeDateTime), Amount = SUM(SomeAmount) FROM #MyHead WHERE SomeDateTime >= '2010' AND SomeDateTime < '2011' GROUP BY DATENAME(mm,SomeDateTime), MONTH(SomeDateTime) ORDER BY MONTH(SomeDateTime) ;
This is the best one, I think. Adding MONTH function won't change the grouping as it's the same and it will still use seek. You can also use DATEPART(mm, SomeDate).
it really isn't the best one. when you compare Jeff's ORDER BY clause vs the one above, Jeff's is more efficient.
I had to test to confirm because I assumed the CAST would cost more, but it doesn't.....
|
|
|
|
|
Forum Newbie
      
Group: General Forum Members
Last Login: Monday, March 26, 2012 6:59 AM
Points: 4,
Visits: 19
|
|
Geoff A (11/15/2010)
Kristian Ask (11/15/2010)
hugo-939487 (11/15/2010)
Another variaton, using the MONTH function: SELECT [Month] = DATENAME(mm,SomeDateTime), Amount = SUM(SomeAmount) FROM #MyHead WHERE SomeDateTime >= '2010' AND SomeDateTime < '2011' GROUP BY DATENAME(mm,SomeDateTime), MONTH(SomeDateTime) ORDER BY MONTH(SomeDateTime) ;
This is the best one, I think. Adding MONTH function won't change the grouping as it's the same and it will still use seek. You can also use DATEPART(mm, SomeDate). it really isn't the best one. when you compare Jeff's ORDER BY clause vs the one above, Jeff's is more efficient. I had to test to confirm because I assumed the CAST would cost more, but it doesn't.....
That's really interesting - I assumed ordering by MONTH(SomeDateTime) would have to be more efficient. I still prefer it aesthetically, but it's a useful reminder not to make assumptions.
|
|
|
|
|
SSC-Addicted
      
Group: General Forum Members
Last Login: Tuesday, June 11, 2013 10:25 AM
Points: 485,
Visits: 1,569
|
|
N.North (11/15/2010)
You could go for casting the month numbers to names in the select rather than in the ORDER BY clause, as it allows you to use MONTH in most places, and DATENAME only once, which feels more natural: SELECT [Month] = DATENAME(mm, DATEADD(mm, MONTH(SomeDateTime), 0)), Amount = SUM(SomeAmount) FROM #MyHead WHERE SomeDateTime >= '2010' AND SomeDateTime < '2011' GROUP BY MONTH(SomeDateTime) ORDER BY MONTH(SomeDateTime)
but your sort is not correct. it puts Feb first and Jan last.....
|
|
|
|
|
Valued Member
      
Group: General Forum Members
Last Login: Wednesday, June 12, 2013 3:29 AM
Points: 53,
Visits: 240
|
|
Geoff A (11/15/2010)
Kristian Ask (11/15/2010)
hugo-939487 (11/15/2010)
Another variaton, using the MONTH function: SELECT [Month] = DATENAME(mm,SomeDateTime), Amount = SUM(SomeAmount) FROM #MyHead WHERE SomeDateTime >= '2010' AND SomeDateTime < '2011' GROUP BY DATENAME(mm,SomeDateTime), MONTH(SomeDateTime) ORDER BY MONTH(SomeDateTime) ;
This is the best one, I think. Adding MONTH function won't change the grouping as it's the same and it will still use seek. You can also use DATEPART(mm, SomeDate). it really isn't the best one. when you compare Jeff's ORDER BY clause vs the one above, Jeff's is more efficient. I had to test to confirm because I assumed the CAST would cost more, but it doesn't.....
You're quite right!
|
|
|
|
|
SSC Journeyman
      
Group: General Forum Members
Last Login: Yesterday @ 11:10 AM
Points: 85,
Visits: 608
|
|
I don't know why people would mark this article down, but people are funny sometimes.
Even though I probably won't use this technique (I can't think of a time when I've only had to report on a single contiguous year's data) I think this is a good article for the following reasons:
1. The article does exactly what it sets out to do. It states what the parameters are, then addresses the problem as laid out. This is spackle, as Jeff said, not SQL wallboard or a SQL stud*.
2. It encourages the reader to think about things in a new way. Too often (and I'm guilty of it too) we look at a problem and pressure-fit a solution from our repertoire. An article like this has a little twist in it that, if you're smart, you'll tuck away for one of those days when you're trying to do something new.
* I think most of us aspire to SQL stud-hood.
|
|
|
|
|
Forum Newbie
      
Group: General Forum Members
Last Login: Monday, June 03, 2013 2:09 PM
Points: 5,
Visits: 76
|
|
I made use of the built-in datepart functions available in SQL, as many of you also demonstrated. I used a sub-query to obtain the same results. If you want to select multiple years, in the Where clause you simply use the "in" instead of "=" operator.
SELECT [Month] ,[Amount] = SUM([Amount]) FROM ( SELECT [SortMonth] = MONTH(SomeDateTime) ,[Month] = DATENAME(mm,SomeDateTime) ,[Amount] = SomeAmount FROM #MyHead WHERE YEAR(SomeDateTime) = 2010 ) a GROUP BY [Month], [SortMonth] ORDER BY [SortMonth]
|
|
|
|
|
Grasshopper
      
Group: General Forum Members
Last Login: Friday, June 14, 2013 11:16 AM
Points: 20,
Visits: 77
|
|
| IE would not permit horizontal scrolling to display either of your queries so I have no idea of what you are proposing. Shame too as I was hoping to send this to a beginning DBA.
|
|
|
|