2014-12-15 5 views
5

Ho una tabella, con i tipi varchar, datetime, datetime:Per ogni giorno tra due date, aggiungere una riga con le stesse informazioni, ma solo quel giorno nelle colonne di inizio/fine

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

che cosa è uno SQL domanda che può cercare di scoprire come fare quel tavolo sia ?:

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

Questo è stato eseguito solo una volta, e su una piccola set di dati. L'ottimizzazione non è necessaria.

+0

quello che è successo in anno a inizio e fine anno –

+0

può essere qualsiasi cosa, l'idea è che iniziano e terminano saranno di tipo datetime. –

+0

Perché i campi 'START' e' END' dell'output sono identici? –

risposta

6

Potrebbe essere necessario un 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 

USCITA:

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 
4

È possibile farlo con una CTE ricorsiva:

;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 

Tuttavia, vi suggerisco di creazione di una tabella di calendario e unendosi ad esso:

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 di entrambe le query: SQL Fiddle

+0

Tutte le date di fine saranno uguali e sbagliate –

+0

Altre parti del prodotto si basano su una data di inizio/fine, la mia funzione presuppone una voce al giorno, quindi non è necessario alcun avvio/fine, ma deve averlo per soddisfare altri requisiti. Se ciò ha senso? –

+0

@JustinWarner Vedo, aggiornato di conseguenza. –

1
;WITH dates 
AS (SELECT (SELECT MIN(start) from table) as date, 
    UNION ALL 
    SELECT 
      Dateadd(day, 1, date), 
    FROM dates 
    WHERE date < (SELECT MAX(end) from table)) 

SELECT name, date as start, date as end 
from table 
RIGHT JOIN dates on date between start and end 
+0

Questo non funzionerà, non è possibile utilizzare 'aggregate' su' parte ricorsiva' di 'CTE' –

+0

Che sono sottoquery, non aggregati sul cte. – overflowed

+0

nella sottoquestione si è utilizzato Aggregato che non è consentito nella 'parte ricorsiva di CTE' –

Problemi correlati