{"id":2372,"date":"2014-12-04T19:10:14","date_gmt":"2014-12-04T19:10:14","guid":{"rendered":"http:\/\/www.sitekickr.com\/blog\/?p=2372"},"modified":"2014-12-04T19:11:37","modified_gmt":"2014-12-04T19:11:37","slug":"mysql-sales-reporting-holiday","status":"publish","type":"post","link":"https:\/\/www.sitekickr.com\/blog\/mysql-sales-reporting-holiday\/","title":{"rendered":"MySQL Sales Reporting by Holiday"},"content":{"rendered":"<p>I have a client is big into reporting. Occasionally, I&#8217;ll get a pretty interesting request that makes total sense in the real world but doesn&#8217;t translate well to database query.<\/p>\n<p>Today, that request was to produce a report to show holiday sales trends. Okay, I first thought that we&#8217;d just do a daily comparison of sales numbers, showing this years sales in one column and last year&#8217;s sales in column number two.<\/p>\n<p>But then I thought about it. We might want to compare how Black Friday 2014 outperformed Black Friday 2013. Since this &#8220;holiday&#8221; falls on a different day each year, this report is not exactly cut and dry.<\/p>\n<p>So, like any good programmer should, I first Google&#8217;d for solutions. Though other developers shared their related experience, nothing match my exact requirements.<\/p>\n<p>Some used a complex stored procedure that followed &#8220;holiday rules&#8221; to produce an exact day given a year and the name of a holiday. This sounded appealing but it was complex and, I thought, difficult to maintain if we want to add more holidays.<\/p>\n<p>I decided to go with a flat &#8220;cross-reference&#8221; table, which would simple have a field for the name of a holiday, and another field for the date. This would require manual entry of the holiday names and dates that you want to track, but in my case, it was only a dozen per year.<\/p>\n<p>I&#8217;ll provide that table structure and data to save you time: <a href=\"\/blog\/src\/sql\/holiday.sql\">Holiday MySQL Table<\/a><\/p>\n<p>By doing a simple JOIN from my orders table against the holiday table, I can easily &#8220;tableize&#8221; a comparison of holiday numbers from year to year:<\/p>\n<pre class=\"prettyprint\"><code>SELECT h.holiday_name, FORMAT(SUM(order_total), 0) as total,\r\n   (SELECT FORMAT(SUM(order_total), 0)\r\n    FROM orders\r\n    INNER JOIN holiday\r\n            ON holiday_date = DATE(order_created)\r\n    WHERE holiday.holiday_name = h.holiday_name\r\n      AND YEAR(holiday_date) = YEAR(o.order_created - INTERVAL 1 YEAR)\r\n   ) as yearBeforeTotal\r\nFROM orders o\r\nINNER JOIN holiday h\r\n        ON h.holiday_date = DATE(order_created)\r\nWHERE YEAR(order_created) = YEAR(NOW())\r\nGROUP BY DATE(order_created)\r\nORDER BY DAYOFYEAR(order_created)<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Not all real-world reporting requirements align well with how your data is organized. In my case, I had to produce sales reports tied to a US Holiday (which varies year-to-year).<\/p>\n","protected":false},"author":1,"featured_media":2376,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"amp_status":""},"categories":[13],"tags":[113],"_links":{"self":[{"href":"https:\/\/www.sitekickr.com\/blog\/wp-json\/wp\/v2\/posts\/2372"}],"collection":[{"href":"https:\/\/www.sitekickr.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.sitekickr.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.sitekickr.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.sitekickr.com\/blog\/wp-json\/wp\/v2\/comments?post=2372"}],"version-history":[{"count":4,"href":"https:\/\/www.sitekickr.com\/blog\/wp-json\/wp\/v2\/posts\/2372\/revisions"}],"predecessor-version":[{"id":2377,"href":"https:\/\/www.sitekickr.com\/blog\/wp-json\/wp\/v2\/posts\/2372\/revisions\/2377"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.sitekickr.com\/blog\/wp-json\/wp\/v2\/media\/2376"}],"wp:attachment":[{"href":"https:\/\/www.sitekickr.com\/blog\/wp-json\/wp\/v2\/media?parent=2372"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.sitekickr.com\/blog\/wp-json\/wp\/v2\/categories?post=2372"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.sitekickr.com\/blog\/wp-json\/wp\/v2\/tags?post=2372"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}