2016-04-15 7 views
0

Ich habe diese Datenstruktur in meinen SQL Server-Datenbankdaten von Zeile schwenken:Wie Spalte mit T-SQL

User   FmDate   ToDate 
------------------------------------ 
Andy   1/10   1/15 
Baey   1/14   1/18 
Christy  1/17   2/18 

Das Datum ist Bereich der Natur Tages, wie kann ich T-SQL schreiben zu verschwenken sie wie Excel, wie gezeigt:

Andy 1/10 
Andy 1/11 
Andy 1/12 
Andy 1/13 
Andy 1/14 
Andy 1/15 
Baey 1/14 
Baey 1/15 
Baey 1/16 
Baey 1/17 
Baey 1/18 
Christy 1/17 
Christy 1/18 
+0

Was der Datentyp Ihrer frei/ –

Antwort

1

Sie können eine tally table verwenden die Termine von FmDate zu ToDate

DECLARE @range INT; 
SELECT @range = MAX(DATEDIFF(DAY, FmDate, ToDate)) + 1 FROM tbl; 

;WITH E1(N) AS(-- 10^1 = 10 rows 
    SELECT 1 FROM(VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1))t(N) 
), 
E2(N) AS(SELECT 1 FROM E1 a CROSS JOIN E1 b), -- 10^2 = 100 rows 
E4(N) AS(SELECT 1 FROM E2 a CROSS JOIN E2 b), -- 10^4 = 10,000 rows 
CteTally(N) AS(
    SELECT TOP(@Range) ROW_NUMBER() OVER(ORDER BY(SELECT NULL)) 
    FROM E4 
), 
CteDates([User], dt) AS(
    SELECT t.[User], DATEADD(DAY, N-1, FmDate) 
    FROM tbl t 
    CROSS JOIN CteTally ct 
    WHERE DATEADD(DAY, N-1, FmDate) <= ToDate 
) 
SELECT * 
FROM CteDates 
ORDER BY [User], dt; 
zu erzeugen

SQL Fiddle

Dies setzt voraus, dass Ihre Daten DATE Format.


vor der Bearbeitung ist Ihr erwartetes Ergebnis eine verschwenkten Version.

Um das Ergebnis des obigen zu schwenken, verwenden Sie eine dynamic crosstab. Legen Sie das Ergebnis der oben auf eine temporäre Tabelle für die Verarbeitung:

IF OBJECT_ID('tempdb..##tembTbl') IS NOT NULL BEGIN 
    DROP TABLE ##tempTbl 
END 

DECLARE @range INT; 
SELECT @range = MAX(DATEDIFF(DAY, FmDate, ToDate)) + 1 FROM tbl; 

;WITH E1(N) AS(-- 10^1 = 10 rows 
    SELECT 1 FROM(VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1))t(N) 
), 
E2(N) AS(SELECT 1 FROM E1 a CROSS JOIN E1 b), -- 10^2 = 100 rows 
E4(N) AS(SELECT 1 FROM E2 a CROSS JOIN E2 b), -- 10^4 = 10,000 rows 
CteTally(N) AS(
    SELECT TOP(@Range) ROW_NUMBER() OVER(ORDER BY(SELECT NULL)) 
    FROM E4 
), 
CteDates([User], dt) AS(
    SELECT t.[User], DATEADD(DAY, N-1, FmDate) 
    FROM tbl t 
    CROSS JOIN CteTally ct 
    WHERE DATEADD(DAY, N-1, FmDate) <= ToDate 
) 
SELECT * 
INTO ##tempTbl 
FROM CteDates; 

DECLARE @sql NVARCHAR(MAX) = ''; 

SELECT @sql = 
'SELECT 
    [User]' + CHAR(10) 

SELECT @sql = @sql + 
' , MAX(CASE WHEN dt = ''' + CONVERT(VARCHAR(8), dt, 112) + ''' THEN ''Y'' ELSE '''' END) AS ' + QUOTENAME(CONVERT(VARCHAR(5), dt, 101)) + CHAR(10) 
FROM (SELECT DISTINCT dt FROM ##tempTbl) t 
ORDER BY dt 

SELECT @sql = @sql + 
'FROM ##tempTbl 
GROUP BY [User];' 

PRINT (@sql); 
EXEC (@sql); 

SQL Fiddle

ERGEBNIS:

| User | 01/10 | 01/11 | 01/12 | 01/13 | 01/14 | 01/15 | 01/16 | 01/17 | 01/18 | 
|---------|-------|-------|-------|-------|-------|-------|-------|-------|-------| 
| Andy |  Y |  Y |  Y |  Y |  Y |  Y |  |  |  | 
| Baey |  |  |  |  |  Y |  Y |  Y |  Y |  Y | 
| Christy |  |  |  |  |  |  |  |  Y |  Y | 
+0

danke, sind Sie sehr kommen . – user1453232

+0

Hast du mir einfach gedankt und mich dann selbst willkommen geheißen? :) –