【问题标题】:Long to wide - SQL [duplicate]长到宽 - SQL [重复]
【发布时间】:2016-09-23 20:17:05
【问题描述】:

我有一张很长的桌子(例如)

    Date        Person    Number
    2015-01-03  A         4
    2015-01-04  A         2
    2015-01-05  A         3
    2015-01-03  B         5
    2015-01-04  B         6
    2015-01-05  B         7
    2015-01-03  C         1
    2015-01-04  C         3
    2015-01-05  C         4
    2015-01-05  D         4
    2015-01-04  E         1
    2015-01-05  E         3

而且我需要它看起来像(宽):

    Date          A    B    C    D    E
    2015-01-03    4    5    1    0    0
    2015-01-04    2    6    3    0    1
    2015-01-05    3    7    4    4    3

任何帮助将不胜感激。我正在使用交易。谢谢。

【问题讨论】:

  • 只有 a、b、c、d、e 还是动态列表?
  • 它的动态 - a,b,c,d,e 就是一个例子。

标签: sql-server tsql


【解决方案1】:

您可以使用条件聚合:

SELECT
    Date,
    [A] = MAX(CASE WHEN Person = 'A' THEN Number ELSE 0 END),
    [B] = MAX(CASE WHEN Person = 'B' THEN Number ELSE 0 END),
    [C] = MAX(CASE WHEN Person = 'C' THEN Number ELSE 0 END),
    [D] = MAX(CASE WHEN Person = 'D' THEN Number ELSE 0 END),
    [E] = MAX(CASE WHEN Person = 'E' THEN Number ELSE 0 END)
FROM #tbl
GROUP BY Date

如果您有未知数量的Persons,那么您必须动态进行:

DECLARE @sql NVARCHAR(MAX) = N'';

SELECT @sql =
'SELECT
    Date' + CHAR(10) +
(
SELECT DISTINCT 
'   , MAX(CASE WHEN Person = ''' + Person + ''' THEN Number ELSE 0 END) AS ' + QUOTENAME(Person) + CHAR(10)
FROM #tbl
FOR XML PATH('')
) +
'FROM #tbl
GROUP BY Date;';

PRINT (@sql);
EXEC (@sql);

ONLINE DEMO

【讨论】:

    【解决方案2】:

    使用 PIVOT:

    select date, isNull([A], 0) as A, 
        isNull([B], 0) as B, 
        isNull([C], 0) as C, 
        isNull([D], 0) as D, 
        isNull([E], 0) as E 
        from
    ( select date, person, number 
        from tbl )  AS SourceTable
    PIVOT
    ( max(number) for
     Person in ( [A], [B], [C], [D], [E]) ) AS PivotTable;
    

    动态版本是:

    DECLARE @columns NVARCHAR(MAX), @whereColumns NVARCHAR(MAX), @sql NVARCHAR(MAX);
    SET @columns = N'';
    SET @whereColumns = N'';
    SELECT @columns += N', isNull(p.' + QUOTENAME(Person) +', 0)  as ' + Person,
           @whereColumns += N', ' +QUOTENAME (Person)
      FROM (select Person from tbl group by Person) AS x;
    SET @sql = N'
    select date, ' +   STUFF(@columns, 1, 2, '') +
    N'
        from
    ( select date, person, number 
        from tbl )  AS SourceTable
    PIVOT
    ( max(number) for
     Person in ( '
      + stuff(@whereColumns, 1, 2, '')
      + ' )
    ) AS P '
    
     print @sql;
     exec (@sql);
    

    【讨论】:

    • 当有问题的列包含数字时,代码是什么,即我目前有一个长格式表,其中列clm_cd 包含10, 20, ..., 50,我想创建列c10, c20, ..., c50跨度>
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-05-18
    • 1970-01-01
    • 2021-08-26
    • 2016-12-28
    • 2021-06-25
    • 2012-12-01
    • 1970-01-01
    相关资源
    最近更新 更多