{"id":34905,"date":"2021-06-24T20:38:33","date_gmt":"2021-06-24T20:38:33","guid":{"rendered":"https:\/\/ittutorial.org\/?p=34905"},"modified":"2021-06-25T09:19:39","modified_gmt":"2021-06-25T09:19:39","slug":"fill-in-missing-dates-for-sql-server-query-output-using-cte","status":"publish","type":"post","link":"https:\/\/ittutorial.org\/fill-in-missing-dates-for-sql-server-query-output-using-cte\/","title":{"rendered":"Fill In Missing Dates for SQL Server Query Output using CTE"},"content":{"rendered":"<p>Last week one of my colleagues requested me to help him write a query to fill in missing dates in query output. I came across couple of solutions, neither seemed convenient to me. So, I compiled my own using recursive CTE or Common Table Expression.<\/p>\n<p><span style=\"text-decoration: underline\"><strong>Problem Statement<\/strong><\/span><\/p>\n<p>Let&#8217;s say we have a table which contains incoming call records of a customer care from 1st to 10th June, 2021. In some days, there is no call record. If we run the GROUP BY statement on datetime column, some days will be missing. Desired output is, missing dates will be 0 value. Sample output will be below:<\/p>\n<p><span style=\"text-decoration: underline\">Query<\/span><\/p>\n<p><code>SELECT CONVERT(varchar(10),B.call_time,111) AS OriginalDate, COUNT(*) as total<br \/>\nFROM Test1 B<br \/>\nGROUP BY CONVERT(varchar(10),B.call_time,111)<br \/>\nORDER BY CONVERT(varchar(10),B.call_time,111)<\/code><\/p>\n<p><span style=\"text-decoration: underline\">Sample Output<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-34909\" src=\"https:\/\/ittutorial.org\/wp-content\/uploads\/2021\/06\/missing_date_1-300x108.png\" alt=\"\" width=\"506\" height=\"182\" srcset=\"https:\/\/ittutorial.org\/wp-content\/uploads\/2021\/06\/missing_date_1-300x108.png 300w, https:\/\/ittutorial.org\/wp-content\/uploads\/2021\/06\/missing_date_1.png 499w\" sizes=\"auto, (max-width: 506px) 100vw, 506px\" \/><\/p>\n<p><span style=\"text-decoration: underline\">Desired Output<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-34910\" src=\"https:\/\/ittutorial.org\/wp-content\/uploads\/2021\/06\/missing_date_2-300x243.png\" alt=\"\" width=\"349\" height=\"283\" srcset=\"https:\/\/ittutorial.org\/wp-content\/uploads\/2021\/06\/missing_date_2-300x243.png 300w, https:\/\/ittutorial.org\/wp-content\/uploads\/2021\/06\/missing_date_2.png 397w\" sizes=\"auto, (max-width: 349px) 100vw, 349px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"text-decoration: underline\"><strong>My Approach to Solution<\/strong><\/span><\/p>\n<p>Rather than using simple GROUP BY query, CTE and SUB QUERY are used. Recursive CTE is used to generate the date range and LEFT OUTER JOIN is used to combine the value with the date. Let&#8217;s explain step-by-step.<\/p>\n<p><span style=\"text-decoration: underline\"><strong>CTE\/Common Table Expression<\/strong><\/span><\/p>\n<p>CTE or Common Table Expression specifies a temporary named result set which is derived from a simple query and defined within the execution scope of a single SELECT\/INSERT\/UPDATE\/DELETE\/MERGE\/CREATE VIEW statement. It can refer to itself also which is called recursive CTE.<\/p>\n<p><span style=\"text-decoration: underline\"><strong>Preparing Data<\/strong><\/span><\/p>\n<p><code>-- Create the table<br \/>\nCREATE TABLE Test1(<br \/>\ncall_time datetime,<br \/>\nname\u00a0\u00a0\u00a0 varchar(10) default ('Mehedi')<br \/>\n)<br \/>\nGO<br \/>\n-- Populate with sample data<br \/>\nINSERT INTO Test1 (call_time, name)<br \/>\nVALUES ('2021-06-01 08:00','A')<br \/>\n,('2021-06-01 09:05','C')<br \/>\n,('2021-06-01 12:50','E')<br \/>\n,('2021-06-01 16:17','D')<br \/>\n,('2021-06-01 18:53','G')<br \/>\n,('2021-06-03 11:07','F')<br \/>\n,('2021-06-03 13:09','A')<br \/>\n,('2021-06-03 16:26','E')<br \/>\n,('2021-06-03 19:56','C')<br \/>\n,('2021-06-03 21:24','A')<br \/>\n,('2021-06-04 19:13','A')<br \/>\n,('2021-06-04 11:45','B')<br \/>\n,('2021-06-04 15:02','C')<br \/>\n,('2021-06-08 23:02','A')<br \/>\n,('2021-06-09 03:04','E')<\/code><\/p>\n<p><span style=\"text-decoration: underline\"><strong>Build The Query<\/strong><\/span><\/p>\n<p>First, we will write a CTE which will generate all the dates within the date range.<\/p>\n<p><code>DECLARE @StartDate DATE, @EndDate DATE<br \/>\nSET @StartDate = '2021-11-01'<br \/>\nSET @EndDate = '2021-11-08'<br \/>\n;WITH cte AS<br \/>\n(\u00a0\u00a0\u00a0 SELECT @StartDate AS sDate<br \/>\nUNION ALL<br \/>\nSELECT DATEADD(DAY,1,sDate)<br \/>\nFROM cte<br \/>\nWHERE sDate &lt; @EndDate<br \/>\n)<br \/>\nSELECT\u00a0 sDate<br \/>\nFROM cte;<\/code><\/p>\n<p>Now this CTE is will be refactored to make a sub query with LEFT OUTER JOIN so that the date which does not have the value appears and contains 0 value.<\/p>\n<p><code>DECLARE @startdate DATETIME = '2021-06-01'<br \/>\nDECLARE @endDate DATETIME = '2021-06-10'<br \/>\n;WITH cte<br \/>\nAS<br \/>\n(<br \/>\nSELECT @startdate as sDate<br \/>\nUNION All<br \/>\nSELECT DATEADD(day,1,sDate) From cte where DATEADD(day,1,sDate) &lt;= @endDate<br \/>\n)<br \/>\nSELECT<br \/>\nC.OriginalDate<br \/>\n,C.total<br \/>\nFROM<br \/>\n(<br \/>\nSELECT CONVERT(varchar(10),A.sDate,111) AS OriginalDate, COUNT(B.call_time) as total<br \/>\nFROM cte A<br \/>\nLEFT OUTER JOIN Test1 B<br \/>\nON A.sDate = CONVERT(varchar(10),B.call_time,111)<br \/>\nGROUP by CONVERT(varchar(10),A.sDate,111)<br \/>\n) C<br \/>\nORDER BY C.OriginalDate<\/code><\/p>\n<p><span style=\"text-decoration: underline\"><strong>Final Output<\/strong><\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-34910\" src=\"https:\/\/ittutorial.org\/wp-content\/uploads\/2021\/06\/missing_date_2-300x243.png\" alt=\"\" width=\"300\" height=\"243\" srcset=\"https:\/\/ittutorial.org\/wp-content\/uploads\/2021\/06\/missing_date_2-300x243.png 300w, https:\/\/ittutorial.org\/wp-content\/uploads\/2021\/06\/missing_date_2.png 397w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/p>\n<p><span style=\"text-decoration: underline\"><strong>Conclusion<\/strong><\/span><\/p>\n<p>Hope, it will be helpful for you. Happy TSQLing!<\/p>\n<p>It&#8217;s also available in my personal <a href=\"https:\/\/www.techearth.xyz\/post\/2021\/06\/23\/fill-in-missing-dates-for-sql-server-query-output-using-cte\">blog<\/a>!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Last week one of my colleagues requested me to help him write a query to fill in missing dates in query output. I came across couple of solutions, neither seemed convenient to me. So, I compiled my own using recursive CTE or Common Table Expression. Problem Statement Let&#8217;s say we have a table which contains &hellip;<\/p>\n","protected":false},"author":10927,"featured_media":34908,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[2227],"tags":[],"class_list":["post-34905","post","type-post","status-publish","format-standard","has-post-thumbnail","","category-sql-server-2"],"aioseo_notices":[],"jetpack_featured_media_url":"https:\/\/ittutorial.org\/wp-content\/uploads\/2021\/06\/Missung-Dates.png","jetpack_sharing_enabled":true,"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/ittutorial.org\/wp-json\/wp\/v2\/posts\/34905","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ittutorial.org\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ittutorial.org\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ittutorial.org\/wp-json\/wp\/v2\/users\/10927"}],"replies":[{"embeddable":true,"href":"https:\/\/ittutorial.org\/wp-json\/wp\/v2\/comments?post=34905"}],"version-history":[{"count":5,"href":"https:\/\/ittutorial.org\/wp-json\/wp\/v2\/posts\/34905\/revisions"}],"predecessor-version":[{"id":34918,"href":"https:\/\/ittutorial.org\/wp-json\/wp\/v2\/posts\/34905\/revisions\/34918"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/ittutorial.org\/wp-json\/wp\/v2\/media\/34908"}],"wp:attachment":[{"href":"https:\/\/ittutorial.org\/wp-json\/wp\/v2\/media?parent=34905"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ittutorial.org\/wp-json\/wp\/v2\/categories?post=34905"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ittutorial.org\/wp-json\/wp\/v2\/tags?post=34905"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}