2015-07-16 6 views
5

Ich habe eine Tabelle, aus der ich Daten unter bestimmten Bedingungen erhalten möchte. Ich erhalte Daten mit unter Abfrage.Wie konvertiert man mehrere Zeilen in eine Zeile mit mehreren Spalten mit Pivot in SQL Server, wenn Daten mit NULL Werten

SELECT track, 
     ytd, 
     weekno, 
     [unit] 
FROM SMIrawdataFinal 
WHERE unit IS NOT NULL AND tracktype='focus' AND track='A' AND ytd IS NOT NULL 

Original Tabelle (Daten) ist wie folgt.

track ytd weekno unit 
A  (Blank) 1  1 
A  (Blank) 2  2 
A  (Blank) 3  3 
A  19  5  5 
A  (Blank) 4  4 

Ich habe unten Daten mit PIVOT in SQL Server. Mein Problem ist Wie kann ich Nullwerte entfernen und die gleichen Daten in einer einzigen Zeile erhalten.

autoId track ytd col4 col3 col2 col1  
------------------------------------------------- 
1   A (Blank) NULL 4  3  2 
2   A  19  5  NULL NULL NULL 

Unten ist mein SQL-Abfrage:

SELECT * 
FROM (
    SELECT track,ytd,weekno,[unit] 
    FROM SMIrawdataFinal 
    WHERE album = 'XYZ' 
     AND unit IS NOT NULL 
     AND tracktype='focus' 
     AND track='A' 
     AND ytd IS NOT NULL 
    ) as s 
PIVOT(
    SUM(unit) 
    FOR weekno in ([5],[4],[3],[2]) 
)AS pivot1 
+0

Was verwenden Sie? SQL Server ODER MySQL? Du hast beide Tags! Aufgrund Ihres Codes würde ich erwarten, dass Sie einen SQL Server ausführen. – Ionic

+0

(Blank) meinst du '' ''? –

+0

Woher kommt die "autoId"? Sie würden auf einer Linie sein, wenn sie das selbe waren. BEARBEITEN SIE: Wenn YTD einmal (leer) und ein anderes Mal "19" ist, könnte es richtig sein, mit zwei Reihen zurückzukommen ... – Shnugo

Antwort

3

Verwenden Sie eine Gruppe mit SUM zu erhalten der gewünschte Ausgang:

SELECT track, 
    SUM(ISNULL(ytd, 0)) AS [ytd], 
    SUM(ISNULL([5], 0)) AS [5], 
    SUM(ISNULL([4], 0)) AS [4], 
    SUM(ISNULL([3], 0)) AS [3], 
    SUM(ISNULL([2], 0)) AS [2] 
    FROM (SELECT track,ytd,weekno,[unit] 
    FROM SMIrawdataFinal where album = 'XYZ' 
      AND unit IS NOT NULL 
      AND tracktype='focus' 
      AND track='A') as s PIVOT 
    (SUM(unit) FOR weekno in ([5],[4],[3],[2]))AS pivot1 
    GROUP BY track 

Output:

012.351.
track | ytd | 5 | 4 | 3 | 2 
    -------------------------------- 
    A  | 19 | 5 | 4 | 3 | 2 
1

Wenn Ihr mit SQL Server und Sie möchten die col4-col1 einer Zeile verketten, können Sie dies so erreichen können:

SELECT p.track, p.ytd, 
    CONVERT(nvarchar(max),ISNULL(p.[5],0)) 
    + CONVERT(nvarchar(max),ISNULL(p.[4],0)) 
    + CONVERT(nvarchar(max),ISNULL(p.[3],0)) 
    + CONVERT(nvarchar(max),ISNULL(p.[2],0)) as asOneRow 
FROM (
    SELECT track, ytd, weekno,[unit] 
    FROM SMIrawdataFinal 
    WHERE album = 'XYZ' 
     AND unit IS NOT NULL 
     AND tracktype='focus' 
     AND track='A' 
     AND ytd IS NOT NULL 
    ) as s 
PIVOT(
    SUM(unit) 
    FOR weekno in ([5],[4],[3],[2]) 
)AS p 

Wenn Sie diese Werte summieren möchten, können Sie dies verwenden:

SELECT p.track, p.ytd, 
    SUM(ISNULL(p.[5],0)) as col4, 
    SUM(ISNULL(p.[4],0)) as col3, 
    SUM(ISNULL(p.[3],0)) as col2, 
    SUM(ISNULL(p.[2],0)) as col1 
FROM (
    SELECT track, ytd, weekno,[unit] 
    FROM SMIrawdataFinal 
    WHERE album = 'XYZ' 
     AND unit IS NOT NULL 
     AND tracktype='focus' 
     AND track='A' 
     AND ytd IS NOT NULL 
    ) as s 
PIVOT(
    SUM(unit) 
    FOR weekno in ([5],[4],[3],[2]) 
)AS p 
GROUP BY p.track, p.ytd 
+1

Warum genau schlagen Sie eine Konvertierung zu 'nvarchar (100)' vor? – OzrenTkalcecKrznaric

+0

Verwechseln Sie eine Zeile mit einer Spalte? – GarethD

+0

Nun, Sie können max verwenden, aber ich denke nicht, dass Zahlen diese Grenzen so schnell überschreiten werden. Sie können das Beispiel unten nehmen, wenn Sie die andere Sache brauchen. – Ionic

1

gründend auf Ihren Beispieldaten und Abfrage Ich habe diese in einzelne Zeilen aus und fügen Sie bitte, wo die Bedingungen in Ihrer Anfrage

declare @t table (track varchar(2),ytd int,weekno int,unit iNT) 
insert into @t (track,ytd,weekno,unit) 
values 
('A',NULL,1,1), 
('A',NULL,2,2), 
('A',NULL,3,3), 
('A',19,5,5), 
('A',NULL,4,4) 

;with CTE AS (
SELECT * FROM (SELECT track,ytd,weekno,[unit] 
FROM @t ) as s PIVOT 
(SUM(unit) FOR weekno in ([5],[4],[3],[2]))AS pivot1) 
Select track,MAX(ytd)As YTD,MAX([5])AS [5],MAX([4])AS [4],MAX([3])AS [3],MAX([2])AS [2] from CTE 
GROUP BY track 

DYNAMIC VERSION

IF OBJECT_ID('tempdb..#t') IS NOT NULL 
DROP TABLE #t 
GO 

CREATE table #t 
(track varchar(2),ytd int,weekno VARCHAR(5),unit INT) 
insert into #t (track,ytd,weekno,unit)values 
('A',NULL,1,1), 
('A',NULL,2,2), 
('A',NULL,3,3), 
('A',19,5,5), 
('A',NULL,4,4) 

DECLARE @statement NVARCHAR(max) 
,@columns NVARCHAR(max) 

SELECT @columns = ISNULL(@columns + ',', '') + N'[' + tbl.weekno + ']' 
FROM (
    SELECT DISTINCT weekno 
    FROM #t 
    ) AS tbl 

SELECT @statement = ' select track, 
MAX(ytd)As YTD, 
MAX([5])AS [5], 
MAX([4])AS [4], 
MAX([3])AS [3], 
MAX([2])AS [2] from (
SELECT * FROM (SELECT track,ytd,weekno,[unit] 
FROM #t ) as s PIVOT 
(SUM(unit) FOR weekno in(' + @columns + ')) as pvt)T 
GROUP BY T.track' 

EXEC sp_executesql @statement = @statement 
0

Ich empfehle Ihnen, Aggregate auf Auswahl und Gruppe für Spur zu verwenden.

CREATE TABLE #t 
(
    track VARCHAR(10), 
    ytd INT, 
    weekno INT, 
    unit INT 
) 
INSERT INTO #t VALUES  
('A',  NULL, 1,  1), 
('A',  NULL, 2,  2), 
('A',  NULL, 3,  3), 
('A',  19,  5,  5), 
('A',  NULL, 4,  4) 

SELECT track, 
     MAX(COALESCE(ytd, 0)) [ytd], 
     MAX(COALESCE([5], 0)) [5], 
     MAX(COALESCE([4], 0)) [4], 
     MAX(COALESCE([3], 0)) [3], 
     MAX(COALESCE([2], 0)) [2] 
FROM (
SELECT track, 
     ytd, 
     weekno, 
     [unit] 
FROM #t 
WHERE unit IS NOT NULL AND track = 'A' 
) as x 
PIVOT 
(
    SUM(unit) 
    FOR weekno IN ([5],[4],[3],[2]) 
)AS piv 
GROUP BY track 

DROP TABLE #t 

OUTPUT:

track ytd 5 4 3 2 
    A  19 5 4 3 2 

SQL FIDDLE

0

Ich denke, es ist besser, zu überlegen, ob es sinnvoll ist, dies zu tun "verschmelzen". Warum haben die Wochen 5 bis 2 alle dieselbe YTD wie 19? Wenn YTD Year To Date ist, sollte es nicht für verschiedene Wochennummern gleich sein. Also mein Vorschlag ist YTD fallen zu lassen.

SELECT * 
FROM (
    SELECT track,/*ytd,*/ weekno,[unit] 
    FROM SMIrawdataFinal 
    WHERE album = 'XYZ' 
     AND unit IS NOT NULL 
     AND tracktype='focus' 
     AND track='A' 
     /*AND ytd IS NOT NULL*/ 
    ) as s 
PIVOT(
    SUM(unit) 
    FOR weekno in ([5],[4],[3],[2]) 
)AS pivot1