Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

For each day between two dates, add a row with the same info but only that day in the start/end columns

I have a table, with types varchar, datetime, datetime:

NAME | START | END
Bob  | 10/30 | 11/2

What's a SQL query can I look up to find out how to make that table be?:

NAME | START | END
Bob  | 10/30 | 10/30
Bob  | 10/31 | 10/31
Bob  | 11/01 | 11/01
Bob  | 11/02 | 11/02

This is only ran once, and on a very small dataset. Optimization isn't necessary.

like image 448
Justin Warner Avatar asked Dec 15 '14 17:12

Justin Warner


People also ask

How can I get data between two dates in SQL?

To find the difference between dates, use the DATEDIFF(datepart, startdate, enddate) function. The datepart argument defines the part of the date/datetime in which you'd like to express the difference.

How do I find the difference between two dates in the same column?

To calculate the difference between two dates in the same column, we use the createdDate column of the registration table and apply the DATEDIFF function on that column. To find the difference between two dates in the same column, we need two dates from the same column.

Can datediff be used in a where clause?

The DATEDIFF function can also be used in a WHERE clause as well as ORDER BY and HAVING clauses. The units of time available for the DATEDIFF are the same as those for the DATEADD function.


2 Answers

May be you need a Recursive CTE.

CREATE TABLE #dates(NAME  VARCHAR(50),START DATETIME,[END] DATETIME)

INSERT INTO #dates
VALUES      ('Bob','2014-10-30','2014-11-02')

DECLARE @maxdate DATETIME = (SELECT Max([end]) FROM   #dates);

WITH cte
     AS (SELECT NAME,
                START,
                [END]
         FROM   #dates
         UNION ALL
         SELECT NAME,
                Dateadd(day, 1, start),
                Dateadd(day, 1, start)
         FROM   cte
         WHERE  start < @maxdate)
SELECT *
FROM   cte 

OUTPUT :

name    START       END
----    ----------  ----------
Bob     2014-10-30  2014-10-30
Bob     2014-10-31  2014-10-31
Bob     2014-11-01  2014-11-01
Bob     2014-11-02  2014-11-02
like image 105
Pரதீப் Avatar answered Sep 20 '22 19:09

Pரதீப்


You can do this with a recursive cte:

;with cte AS (SELECT Name,Start,[End]
              FROM YourTable
              UNION  ALL
              SELECT Name
                    ,DATEADD(day,1,Start)
                    ,[End]
              FROM cte
              WHERE Start < [End])
SELECT Name, Start, Start AS [End]
FROM cte

However, I suggest creating a calendar table and joining to it:

SELECT a.Name,b.CalendarDate AS Start, b.CalendarDate AS [End]
FROM YourTable a
JOIN tlkp_Calendar b
  ON b.CalendarDate BETWEEN a.[Start] AND a.[End]

Demo of both queries: SQL Fiddle

like image 30
Hart CO Avatar answered Sep 21 '22 19:09

Hart CO