简体   繁体   English

当数据具有NULL值时,如何使用SQL Server中的数据透视表将多行转换为多列的一行

[英]How to convert multiple rows into one row with multiple columns using Pivot in SQL Server when data having NULL values

I have a table from which I want to get data under some conditions. 我有一个要在某些情况下从中获取数据的表。 I am getting data with below query. 我正在使用以下查询获取数据。

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

Original table (data) is like below. 原始表(数据)如下所示。

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

I got below data using PIVOT in sql server. 我在SQL Server中使用PIVOT得到了以下数据。 My problem is how can I remove null values and get the same data in one single row. 我的问题是如何删除空值并在一行中获取相同的数据。

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

Below is my SQL 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

Use a group by with SUM to get the desired output: 与SUM一起使用group by以获得所需的输出:

    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: 输出:

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

If your using SQL Server and you like to concatenate the col4 to col1 to one row, you can achieve this like that: 如果您使用的是SQL Server,并且希望将col4col1连接到一行,则可以这样实现:

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

If you want to sum those values up you can use this: 如果要对这些值求和,可以使用以下方法:

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

basing on your sample data and query i have made this into single row and please add where conditions in your 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

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

I suggest you to use aggregates on select and 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

OUTPUT: 输出:

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

SQL FIDDLE SQL字段

I think it is better to think whether it is reasonable to doing this "merge". 我认为最好考虑进行此“合并”是否合理。 Why weekno 5 to 2 all have same YTD as 19? 为什么第5周到第2周的YTD与第19周相同? If YTD is Year To Date, it should not be same for different week numbers. 如果YTD是年初至今,则不同的星期数应该不相同。 So my suggestion is to drop YTD. 所以我的建议是放弃年初至今。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 SQL插入一行或多行数据? - SQL Insert one row or multiple rows data? 使用LINQ查询将多行转换为多列单行 - Convert multiple rows into a single row with multiple columns using LINQ query 使用StringBuilder和DataTable,当只有一行时,如何在不中断的情况下返回三列中的多行? - Using StringBuilder and a DataTable, How do I return multiple rows in three columns without breaking when there is only one row? SQL从两个表(一行->多行)中选择数据 - SQL Select data from two tables (one row -> multiple rows) SQL:如何从一个表中选择多个值作为单独的列 - SQL: How to select multiple values from one table as seperate columns 如何使用linq从多个行中提取特定的列值 - How to extract particular columns values from multiple rows using linq 如何获取SQL Server 2008中最后输入的行的多个值? - How to get multiple values of last entered row in SQL Server 2008? 如何删除数据表中所有行上具有空值或空白值的列 - How to remove columns having null or blank values on all rows in Datatable 使用多个不同的列来匹配SQL Server数据库中的数据 - Match data in SQL Server database using multiple and varying columns 当多列中的数据匹配时,如何合并DataTable中的行? - How to merge rows in a DataTable when data in multiple columns match?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM