【问题标题】:How to pivot data in SQL with multiple conditions如何在具有多个条件的 SQL 中透视数据
【发布时间】:2020-01-30 06:29:16
【问题描述】:

我正在处理一个看起来像这样的数据

我想以这种方式旋转它:

我是这样写的:

select * 
  from (select * FROM records) as test
  PIVOT (
  max(value) for
  [Question_ID] in ((SELECT distinct [Question_ID] from records order by 1))) AS PivotTable

你能帮帮我吗?

【问题讨论】:

  • 您使用的是哪个 DBMS?还要以text 格式发布示例数据,而不是图片
  • 看起来像这样的数据替换为 CREATE TABLE + INSERT INTO 脚本。并指定 DBMS,包括其版本。
  • @ArunPalanisamy - Sql 服务器
  • @Akina - 我是 SQL 新手,了解 ddl 和 dml 并使用 MSSMS
  • SSMS 可能会生成表的 DDL 和表的数据 DML - 使用。

标签: sql sql-server pivot


【解决方案1】:

如果你知道PIVOT中的列数,你可以像下面这样直接硬编码。

SELECT * FROM
(
SELECT * FROM test
) t
PIVOT (
  MAX(value) for
  [Question_ID] in ([120],[122],[149],[150],[151],[189],[253],[554],[774] )) AS Pivot_Table

如果没有,您必须使用Dynamic Pivot table 来获取未知数量的列值。

DECLARE 
    @columns NVARCHAR(MAX) = '', 
    @sql     NVARCHAR(MAX) = '';

-- select the QuestionIDs
SELECT 
    @columns+=QUOTENAME(Question_ID) + ','
FROM 
    test
GROUP BY Question_ID
ORDER BY Question_ID;

-- remove the last comma
SET @columns = LEFT(@columns, LEN(@columns) - 1);

-- construct dynamic SQL
SET @sql ='
SELECT * FROM   
(
    SELECT * FROM TEST
) t 
PIVOT(
     MAX(value) for 
     [Question_ID] IN ('+ @columns +')
) AS pivot_table;';

-- execute the dynamic SQL
EXECUTE sp_executesql @sql;

CHECK DEMO HERE

【讨论】:

    【解决方案2】:

    你得到了你想要的结果

        select * 
      from (select * FROM #temp) as test--your table name replace with #temp
      PIVOT (
      max(value) for
      [Question_ID] in ([120],[122],[149],[150],[151],[189],[253],[554],[774] )) AS PivotTable
    

    或者如果你想动态查询

      DECLARE @cols AS NVARCHAR(MAX),
        @query  AS NVARCHAR(MAX);
    
    SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(Question_ID) 
                FROM #temp c
                FOR XML PATH(''), TYPE
                ).value('.', 'NVARCHAR(MAX)') 
            ,1,1,'')
    
            --print @cols
    set @query = 'SELECT ID, ' + @cols + ' from 
                (
                    select ID
                        , Question_ID
                        , [Value]
                    from #temp
               ) x
                pivot 
                (
                     max([Value])
                    for [Question_ID] in (' + @cols + ')
                ) p '
    
    
    execute(@query)
    
    drop table #temp
    
    
    ----------
    

    【讨论】:

    • 我尝试了同样的方法,我得到了输出,但我想自动化问题 ID,因为有数百个问题 ID
    • 你想要动态的?
    【解决方案3】:

    如果你确定列数不会改变,那么你可以使用case语句

    CREATE TABLE #TBL (ID INT, Question_ID INT, [Value] VARCHAR(20))
    INSERT INTO #TBL VALUES
    (1,149,'abc'),(1,150,'def'),(1,151,'aff'),(1,122,'www'),
    (2,120,'add'),(2,150,'sub'),(2,189,'asf'),(3,253,'asd'),
    (3,150,'gfre'),(3,554,'cvew'),(3,744,'qwert')
    -- aNSWER
    SELECT
            ID,
             MAX(CASE WHEN Question_ID = 149 THEN [Value] END) AS '149',
             MAX(CASE WHEN Question_ID = 150 THEN [Value] END) AS '150',
             MAX(CASE WHEN Question_ID = 151 THEN [Value] END) AS  '151',
             MAX(CASE WHEN Question_ID = 122 THEN [Value] END) AS '122',
             MAX(CASE WHEN Question_ID = 120 THEN [Value] END) AS '120',
             MAX(CASE WHEN Question_ID = 150 THEN [Value] END) AS '150',
             MAX(CASE WHEN Question_ID = 189 THEN [Value] END) AS '189',
             MAX(CASE WHEN Question_ID = 253 THEN [Value] END) AS '253',
             MAX(CASE WHEN Question_ID = 150 THEN [Value] END) AS '150',
             MAX(CASE WHEN Question_ID = 554 THEN [Value] END) AS '554',
             MAX(CASE WHEN Question_ID = 744 THEN [Value] END) AS '744'             
    FROM #TBL
            GROUP BY ID
    DROP TABLE #TBL
    

    输出

    ID  149   150   151  122    120   150   189   253   150   554   744
    1   abc   def   aff  www    NULL  def   NULL  NULL  def   NULL  NULL
    2   NULL  sub   NULL NULL   add   sub   asf   NULL  sub   NULL  NULL
    3   NULL  gfre  NULL NULL   NULL  gfre  NULL  asd   gfre  cvew  qwert
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-16
      • 2015-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多