【问题标题】:How to collapse multiple rows into one on a pivot table如何在数据透视表上将多行合并为一行
【发布时间】:2019-10-03 16:26:48
【问题描述】:

我在 SQL 代码方面相对缺乏经验,所以就这样吧。

我想从表中提取数据并使用 PIVOT 将值转换为列标题。

我已经设法使用 PIVOT 命令(和动态字段名称)实现了我想要的,但我希望针对单个 ref 的所有值都会出现在一行上。但是,对于每个代码,我都会在原始表中得到一个值(请参见下面的结果)。

使用 CROSS APPLY 似乎是可行的方法(在我的代码示例中已注释掉),但我遇到了一些问题:

  1. 我无法理解它是如何工作的,因此根据我的场景调整在线示例需要进行一些猜测工作。
  2. 根据此站点上的另一篇文章,我在命令中输入了(我认为是)正确的引用: Pivot a table on a value but group the data on one line by another? 他们声称 VALUES 中的两个值必须是相同的数据类型才能使非透视过程起作用。但是,将 'value' 设置为 varchar(10) 会阻止 SUM 函数在 PIVOT 语句中工作。以十进制/浮点数运行它会产生所有 NULL 结果。
  3. 使用 'value' set decimal 包括 GROUP BY 语句确实会产生一行数据,但是(如第 2 点)所有代码值都是 NULL。

希望这一切都有意义。请建议我如何将下面的结果折叠成一行。提前致谢。

DECLARE @CODES nvarchar(max)
select @CODES =
    stuff(
    (
    select distinct ',[' + code + ']'
    from codetable
    for xml path('')
    ),
    1,1,'')

DECLARE @SQL nvarchar(max)
SET @SQL = 
N'
SELECT
    ref,
    ' + @CODES + ',
FROM
    codetable
    --CROSS APPLY
    --(
 --   VALUES
 --     (''code'', convert(varchar(10), code, 120)),
 --     (''value'', convert(decimal, value))
    --) CA (CODE, VAL)
PIVOT(SUM(value)
    FOR code IN (' + @CODES + '))
    AS PVTTable2
WHERE
    ref = ''101'' AND end_date IS NULL
GROUP BY ref,' + @CODES + '
'
exec sp_executesql @SQL
My original table is like this:
-------------------------
|ref    |CODES  |VALUE  |
-------------------------
|101    |CODE4  |20     |
|101    |CODE1  |2      |
|101    |CODE7  |38     |


The results I get are:
-------------------------------------------------------------------------
|ref    |CODE1  |CODE2  |CODE3  |CODE4  |CODE5  |CODE6  |CODE7  |CODE8  |
-------------------------------------------------------------------------
|101    |NULL   |NULL   |NULL   |20     |NULL   |NULL   |NULL   |NULL   |
|101    |2      |NULL   |NULL   |NULL   |NULL   |NULL   |NULL   |NULL   |
|101    |NULL   |NULL   |NULL   |NULL   |NULL   |NULL   |38     |NULL   |

【问题讨论】:

  • 用 SELECT .. GROUP BY 包装您的查询
  • 嗨,跑步:select * from ( <all code below> ) GROUP BY ref 给我Incorrect syntax near the keyword 'GROUP'.

标签: sql duplicates pivot unpivot


【解决方案1】:

枢轴应该写成:

DECLARE @cols AS NVARCHAR(MAX),@query  AS NVARCHAR(MAX);

SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(T.CODES) 
            FROM codetable T
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')


set @query = 'SELECT ref, ' + @cols + ' from 
            (
             SELECT
                 ref, --< grouping column >,
                 CODES, --< spreading column >, 
                 VALUE --< aggregation column >
             FROM codetable
           ) PivotData
            pivot 
            (
                sum(VALUE)
                for CODES in (' + @cols + ')
            ) p '

exec sp_executesql @query

sample code here..

【讨论】:

    【解决方案2】:

    仅限GROUP BY ref

    DECLARE @CODES nvarchar(max)
    select @CODES =
        stuff(
        (
        select distinct ',[' + code + ']'
        from codetable
        for xml path('')
        ),
        1,1,'');
    
    DECLARE @CODESGrp nvarchar(max)
    select @CODESGrp =
        stuff(
        (
        select distinct ',min([' + code + '])'
        from codetable
        for xml path('')
        ),
        1,1,''); 
    
    DECLARE @SQL nvarchar(max);
    SET @SQL = 'SELECT  ref,' + @CODESGrp 
    + ' FROM  codetable '
    + ' PIVOT(SUM(value) FOR code IN (' + @CODES + ')) AS PVTTable2'
    + ' WHERE ref = 101 GROUP BY ref' ;
    
    exec sp_executesql @SQL;
    

    【讨论】:

    • 感谢您的回复。 Deepshikha 的解决方案对我有用,但如果我需要再次修改代码,我会回到你的解决方案。
    猜你喜欢
    • 2019-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-20
    • 2019-07-09
    • 1970-01-01
    • 2013-05-16
    相关资源
    最近更新 更多