当数据具有NULL值时,如何使用SQL Server中的Pivot将多行转换为多行

时间:2015-07-16 06:43:05

标签: c# sql sql-server pivot-table

我有一张表,我希望在某些条件下获取数据。我正在使用以下查询获取数据。

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

原始表格(数据)如下所示。

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

我在sql server中使用PIVOT得到了以下数据。我的问题是 如何删除空值并在一行中获取相同的数据。

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

以下是我的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

5 个答案:

答案 0 :(得分:3)

使用带有SUM的分组来获得所需的输出:

    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

输出:

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

答案 1 :(得分:1)

如果你使用SQL Server并且想要将col4连接到col1到一行,你可以这样做:

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

如果您想将这些值相加,可以使用:

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

答案 2 :(得分:1)

根据您的示例数据和查询,我已将其设为单行,请在查询中添加条件

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

答案 3 :(得分:0)

我建议你在select和group by track上使用聚合。

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

输出:

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

SQL FIDDLE

答案 4 :(得分:0)

我认为最好还是认为这种“合并”是否合理。为什么周五5到2都有与19相同的年初至今?如果年初至今为年,则不同周数不应相同。所以我的建议是放弃年初至今。

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