{"id":5999,"date":"2011-04-30T18:48:24","date_gmt":"2011-04-30T09:48:24","guid":{"rendered":"http:\/\/haakondahl.com\/blog\/?p=472"},"modified":"2011-04-30T18:48:24","modified_gmt":"2011-04-30T09:48:24","slug":"sql-query-of-the-day-group-by-year","status":"publish","type":"post","link":"https:\/\/balldiamondball.com\/blog\/sql-query-of-the-day-group-by-year\/","title":{"rendered":"SQL Query of the Day &#8212; Group By Year"},"content":{"rendered":"<p>This fellow has a blog, and it&#8217;s good: <a href=\"http:\/\/www.sqldisco.com\/?p=6\">Grouping datetime by date in T-SQL \u00ab SQL Disco<\/a>.\u00a0 Many times in SQL you need to group by year, or by date, and what you have to work with is a big nasty DATETIME field.\u00a0 I needed to find out how many updates had been done each year, and I had gnat&#8217;s ass quality timestamps, down to the second.<\/p>\n<p>I know what you&#8217;re thinking, but if you use CONVERT(dtgMyDate), you&#8217;re doing it wrong, as our friend at SQL DISCO points out.\u00a0 In his example, he groups by day; in this one, I have modified it to group by year:<\/p>\n<p><code>SELECT DATEADD(yyyy,(DATEDIFF(yyyy,0,dtgMyDate)),0),<br \/>\nCOUNT(*)<br \/>\nFROM Table1 GROUP BY DATEADD(yyyy,(DATEDIFF(yyyy,0,dtgMyDate)),0)<\/code><\/p>\n<p>You see what he does there?  Instead of costly CONVERT, CAST, or other time\/power wasting (God forbid, parsing for text and casting back to numbers), he leverages the fact that it&#8217;s already a date, and the machine already understands it as a date, and a date ain&#8217;t nothin&#8217; but a number to a computer (okay, an offset from an agreed-upon date, but let&#8217;s keep this friendly).  <em>Same for time<\/em>.<\/p>\n<p>All he&#8217;s doing there is taking the DATETIME, subtracting zero from it but critically <em>in units of years<\/em> (the DATEDIFF) and then adding that many years back to zero (the DATEADD).  Finally, because it was already understood as a DATETIME, it still is, but we have set everything except the year to zero (or one, as necessary).  The result is not 2009, but 1\/1\/2009 12:00:00.  This means that we may now group on it and everything in that year will show up with the same month, day, hour, minute, and second.  If we wanted to, we could format the output to show just a year, but leave that for the reporting&#8211;I work in the aggregation department.<\/p>\n<div class=\"pld-like-dislike-wrap pld-template-1\">\r\n    <div class=\"pld-like-wrap  pld-common-wrap\">\r\n    <a href=\"https:\/\/balldiamondball.com\/blog\/wp-login.php\" class=\"pld-like-trigger pld-like-dislike-trigger  \" title=\"\" data-post-id=\"5999\" data-trigger-type=\"like\" data-restriction=\"user\" data-already-liked=\"0\">\r\n                        <i class=\"fas fa-thumbs-up\"><\/i>\r\n                <\/a>\r\n    <span class=\"pld-like-count-wrap pld-count-wrap\">    <\/span>\r\n<\/div><div class=\"pld-dislike-wrap  pld-common-wrap\">\r\n    <a href=\"https:\/\/balldiamondball.com\/blog\/wp-login.php\" class=\"pld-dislike-trigger pld-like-dislike-trigger  \" title=\"\" data-post-id=\"5999\" data-trigger-type=\"dislike\" data-restriction=\"user\" data-already-liked=\"0\">\r\n                        <i class=\"fas fa-thumbs-down\"><\/i>\r\n                <\/a>\r\n    <span class=\"pld-dislike-count-wrap pld-count-wrap\"><\/span>\r\n<\/div><\/div>","protected":false},"excerpt":{"rendered":"<p>This fellow has a blog, and it&#8217;s good: <a href=\"http:\/\/www.sqldisco.com\/?p=6\">Grouping datetime by date in T-SQL \u00ab SQL Disco<\/a>.\u00a0 Many times in SQL you need to group by year, or by date, and what you have to work with is a big nasty DATETIME field.\u00a0 I needed to find out how many updates had been done each year, and I had gnat&#8217;s ass quality timestamps, down to the second.<\/p>\n<p>I know what you&#8217;re thinking, but if you use CONVERT(dtgMyDate), you&#8217;re doing it wrong, as our friend at SQL DISCO points out.\u00a0 In his example, he groups by day; in this one, I have modified it to group by year:<\/p>\n<p><code>SELECT DATEADD(yyyy,(DATEDIFF(yyyy,0,dtgMyDate)),0),<br \/> COUNT(*)<br \/> FROM Table1 GROUP BY DATEADD(yyyy,(DATEDIFF(yyyy,0,dtgMyDate)),0)<\/code><\/p>\n<p>You see what he does there? Instead of costly CONVERT, &#8230; <a href=\"https:\/\/balldiamondball.com\/blog\/sql-query-of-the-day-group-by-year\/\"> Continue reading <span class=\"meta-nav\">&rarr; <\/span><\/a><\/p>\n","protected":false},"author":34128,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[239,261],"tags":[],"class_list":["post-5999","post","type-post","status-publish","format-standard","hentry","category-computers","category-sql"],"_links":{"self":[{"href":"https:\/\/balldiamondball.com\/blog\/wp-json\/wp\/v2\/posts\/5999","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/balldiamondball.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/balldiamondball.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/balldiamondball.com\/blog\/wp-json\/wp\/v2\/users\/34128"}],"replies":[{"embeddable":true,"href":"https:\/\/balldiamondball.com\/blog\/wp-json\/wp\/v2\/comments?post=5999"}],"version-history":[{"count":0,"href":"https:\/\/balldiamondball.com\/blog\/wp-json\/wp\/v2\/posts\/5999\/revisions"}],"wp:attachment":[{"href":"https:\/\/balldiamondball.com\/blog\/wp-json\/wp\/v2\/media?parent=5999"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/balldiamondball.com\/blog\/wp-json\/wp\/v2\/categories?post=5999"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/balldiamondball.com\/blog\/wp-json\/wp\/v2\/tags?post=5999"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}