【问题标题】:How to transform rows into column? [duplicate]如何将行转换为列? [复制]
【发布时间】:2016-01-04 08:24:09
【问题描述】:

我有一张这样的表,该表中的所有用户只有两个功能

+-------+---------+-----------+----------+
| User  | Feature | StartDate | EndDate  |
+-------+---------+-----------+----------+
| Peter |   F1    | 2015/1/1  | 2015/2/1 |
| Peter |   F2    | 2015/3/1  | 2015/4/1 |
| John  |   F1    | 2015/5/1  | 2015/6/1 |
| John  |   F2    | 2015/7/1  | 2015/8/1 |
+-------+---------+-----------+----------+

我想变身

+-------+--------------+------------+--------------+------------+
| User  | F1_StartDate | F1_EndDate | F2_StartDate | F2_EndDate |
+-------+--------------+------------+--------------+------------+
| Peter |   2015/1/1   |  2015/2/1  |   2015/3/1   |  2015/4/1  |
| John  |   2015/5/1   |  2015/6/1  |   2015/7/1   |  2015/8/1  |
+-------+--------------+------------+--------------+------------+

【问题讨论】:

  • 标记使用的 dbms 产品,因为您可能需要在此处使用特定于产品的功能。
  • 这被称为换位,通常是一种不好的做法。然而,这是一个通用的解决方案stackoverflow.com/questions/13372276/…。诀窍只是在同一张桌子上进行多次选择并加入它
  • @pdem 在数据透视表中呈现数据怎么会是不好的做法?

标签: sql sql-server


【解决方案1】:

如果您使用的是 SQL Server 2005 或更高版本,PIVOT 就是您要找的。​​p>

【讨论】:

  • 是的,首先我使用 PIVOT 将其转换为像 [Name]、[F1]、[F2] 这样的 ResultSet,然后使用 F1 F2 作为键加入原始表
【解决方案2】:

执行此类操作的最佳通用方法是简单的group by 语句。这应该适用于所有主要的 ODBMS:

select user,
       max(case when feature='F1' then StartDate else null end) F1_StartDate,
       max(case when feature='F1' then EndDate else null end) F1_EndDate,
       max(case when feature='F2' then StartDate else null end) F2_StartDate,
       max(case when feature='F2' then EndDate else null end) F2_EndDate
    from table 
    group by user

注意: 如 cmets 中所述,这通常是不好的做法,因为根据您的需要,它会使数据更难处理。但是,在某些情况下,当您的值数量有限时,它是有意义的。

【讨论】:

    【解决方案3】:

    这有点像CTE

    ;WITH CTE AS (
    SELECT [User], [Feature] + '_StartDate' AS [Type], StartDate AS [Date]
    FROM Table1
    UNION ALL
    SELECT [User], [Feature] + '_EndDate' AS [Type], EndDate AS [Date]
    FROM Table1)
    SELECT * FROM CTE
    PIVOT(MAX([Date]) FOR [Type] IN ([F1_StartDate],[F2_StartDate], [F1_EndDate], [F2_EndDate])) PIV
    

    【讨论】:

      【解决方案4】:

      像这样使用UNPIVOT & PIVOT

      测试数据:

      DECLARE @t table
        (User1 varchar(20),Feature char(2),StartDate date,EndDate date)
      INSERT @t values
      ('Pete','F1','2015/1/1 ','2015/2/1'),
      ('Pete','F2','2015/3/1 ','2015/4/1'),
      ('John','F1','2015/5/1 ','2015/6/1'),
      ('John','F2','2015/7/1 ','2015/8/1')
      

      查询:

      ;WITH CTE AS
      (
        SELECT User1, date1, Feature + '_' +  Seq cat
        FROM @t as p  
        UNPIVOT      
        (date1 FOR Seq IN           
        ([StartDate], [EndDate]) ) AS unpvt  
      )
      SELECT * FROM CTE
      PIVOT
      (MIN(date1)
      FOR cat
      IN ([F1_StartDate],[F1_EndDate],[F2_StartDate],[F2_EndDate])
      ) as p
      

      结果:

      User1  F1_StartDate  F1_EndDate  F2_StartDate  F2_EndDate
      John   2015-05-01    2015-06-01  2015-07-01    2015-08-01
      Pete   2015-01-01    2015-02-01  2015-03-01    2015-04-01
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-04-28
        • 2021-05-26
        • 2017-05-09
        • 1970-01-01
        • 2016-09-07
        • 2016-04-09
        • 1970-01-01
        相关资源
        最近更新 更多