2015-07-16 11 views
5

Ho una tabella da cui voglio ottenere i dati in alcune condizioni. Sto ottenendo i dati con la query sottostante.Come convertire più righe in una riga con più colonne utilizzando Pivot in SQL Server quando i dati hanno valori NULL

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

La tabella originale (dati) è come di seguito.

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

Ho ottenuto i dati sotto utilizzando PIVOT in SQL Server. Il mio problema è come posso rimuovere valori nulli e ottenere gli stessi dati in una singola riga.

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

Qui di seguito è la mia query SQL:

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

Che cosa usi? SQL Server O MySQL? Hai entrambi i tag! A causa del tuo codice mi aspetterei che tu eseguissi un server SQL. – Ionic

+0

(Vuoto) intendi ''''? –

+0

Da dove proviene "autoId"? Sarebbero su una riga, se fossero gli stessi probabilmente .. EDIT: Se ytd è una volta (vuoto) e un'altra volta "19" potrebbe essere corretto tornare con due righe ... – Shnugo

risposta

3

Utilizzare un gruppo di con somma per ottenere l'uscita desiderata:

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 

uscita:

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

Se la vostra utilizzando SQL Server e ti piace per concatenare il col4-col1 a una riga, si può raggiungere questo genere:

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 

Se si desidera sommare tali valori è possibile utilizzare questo:

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

Perché stai suggerendo la conversione in 'nvarchar (100)'? – OzrenTkalcecKrznaric

+0

Stai confondendo una riga con una colonna? – GarethD

+0

Bene, puoi usare max, ma non penso che i numeri superino quei limiti così velocemente. Puoi fare l'esempio qui sotto se ti serve l'altra cosa. – Ionic

1

basandosi sui dati di esempio e di query Ho fatto questo in un'unica fila e si prega di aggiungere dove le condizioni nella query

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 

versione dinamica

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

Ti suggerisco di utilizzare gli aggregati su Seleziona e raggruppa per traccia.

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 

USCITA:

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

SQL FIDDLE

0

penso che sia meglio pensare se sia ragionevole per fare questo "merge". Perchè weekno 5 a 2 tutti hanno lo stesso YTD di 19? Se YTD è Anno A Data, non dovrebbe essere lo stesso per i diversi numeri di settimana. Quindi il mio suggerimento è di abbandonare l'anno.

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