Sql 在不使用聚合的情况下转置行和列

Sql 在不使用聚合的情况下转置行和列,sql,sql-server,tsql,pivot,unpivot,Sql,Sql Server,Tsql,Pivot,Unpivot,我有以下数据集 Date Field1 Col1 Col2 Col3 2012/07/02 Customer1 CL DS RT 2012/07/03 Customer1 DS RT 700 2012/07/04 Customer1 DS RT 700 2012/07/02 Customer2 CL DS RT 201

我有以下数据集

Date            Field1        Col1  Col2    Col3
2012/07/02      Customer1      CL   DS      RT
2012/07/03      Customer1      DS   RT      700
2012/07/04      Customer1      DS   RT      700
2012/07/02      Customer2      CL   DS      RT
2012/07/03      Customer2      DS   RT      1500
2012/07/04      Customer2      DS   RT      1500
2012/07/02      Customer3      CL   DS      RT
2012/07/03      Customer3      DS   RT      6000
2012/07/04      Customer3      DS   RT      6000
2012/07/02      Customer4      CL   RC      RT
2012/07/03      Customer4      RC   RT      4900
2012/07/04      Customer4      RC   RT      4900
我希望输出如下:

Field1  2012/07/02  2012/07/03  2012/07/04
Col1    Customer1   CL  DS  DS
Col2    Customer1   DS  RT  RT
Col3    Customer1   RT  700 700
Col1    Customer2   CL  DS  DS
Col2    Customer2   DS  RT  RT
Col3    Customer2   RT  1500    1500
Col1    Customer3   CL  DS  DS
Col2    Customer3   DS  RT  RT
Col3    Customer3   RT  6000    6000
Col1    Customer4   CL  RC  RC
Col2    Customer4   RC  RT  RT
Col3    Customer4   RT  4900    4900

问题还在于我有一个不固定数量的客户(Field1)&不固定数量的日期。

如果没有聚合,您不需要这样做,但您确实需要使用动态SQL来完成。搜索“SQLDynamicPivot”,你会发现很多关于它的帖子。 比如:


但最好是在客户机中执行此操作,因为SQL的客户机希望提前知道生成了哪些列。

您尝试执行的操作被称为。有两种方法可以做到这一点,一种是使用静态透视(其中硬编码所有要转换的值),另一种是使用动态透视(其中值是在执行时确定的)

静态版本(请参阅):

动态轴(请参见):

当您不知道需要转换为列的项数时,动态透视是一个很好的选择。两者将产生相同的结果

编辑#1,如果希望日期列按特定顺序排列-desc等,则将使用以下命令获取日期(请参阅):

你的问题必须使用

您可以使用以下查询:

CREATE TABLE mytable(date DATE, Field1 NVARCHAR(50), col1 NVARCHAR(30), col2 NVARCHAR(30),col3 NVARCHAR(30))
INSERT INTO mytable(date,Field1,col1,col2,col3)
VALUES('2012/07/02','Customer1','CL','DS','RT')
...

SELECT Col, Field1, [2012/07/02],[2012/07/03],[2012/07/04]
FROM (SELECT Field1, 'Col1' AS Col, Date, Col1 AS ColVal
      FROM MyTable

      UNION ALL

      SELECT Field1, 'Col2' , Date, Col2 AS ColVal
      FROM MyTable

      UNION ALL 

      SELECT Field1, 'Col3' , Date, Col3 AS Col
      FROM MyTable
      )AS P
PIVOT (MIN(Colval) FOR Date IN ([2012/07/02],[2012/07/03],[2012/07/04])) AS Pvt
ORDER BY Field1, Col

我还需要正确地安排日期。我如何在动态版本中做到这一点,因为目前添加了更多数据,排序不正确?@user1627440请查看我的编辑,在获取要透视的列列表时,您将稍微更改代码。
DECLARE @colsUnpivot AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX),
    @colsPivot as  NVARCHAR(MAX)

select @colsUnpivot = stuff((select ','+quotename(C.name)
         from sys.columns as C
         where C.object_id = object_id('yourTable') and
               C.name like 'col%'
         for xml path('')), 1, 1, '')

select @colsPivot = STUFF((SELECT distinct ', ' + QUOTENAME(convert(char(10), dt, 120))
                    from yourTable
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 
          'SELECT col, field1, ' + +@colsPivot+ '
           FROM
           (
              select dt, field1, col, value
              from yourTable
              unpivot
              (
                value for col in ('+ @colsUnpivot+')
              ) u
           )x1
           pivot
           (
             min(value)
             for dt in ('+@colsPivot+')
           ) p '

exec(@query)
select @colsPivot = STUFF((SELECT ', ' + QUOTENAME(convert(char(10), dt, 120))
                    from yourTable
                    group by dt
                    ORDER by dt desc
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')
CREATE TABLE mytable(date DATE, Field1 NVARCHAR(50), col1 NVARCHAR(30), col2 NVARCHAR(30),col3 NVARCHAR(30))
INSERT INTO mytable(date,Field1,col1,col2,col3)
VALUES('2012/07/02','Customer1','CL','DS','RT')
...

SELECT Col, Field1, [2012/07/02],[2012/07/03],[2012/07/04]
FROM (SELECT Field1, 'Col1' AS Col, Date, Col1 AS ColVal
      FROM MyTable

      UNION ALL

      SELECT Field1, 'Col2' , Date, Col2 AS ColVal
      FROM MyTable

      UNION ALL 

      SELECT Field1, 'Col3' , Date, Col3 AS Col
      FROM MyTable
      )AS P
PIVOT (MIN(Colval) FOR Date IN ([2012/07/02],[2012/07/03],[2012/07/04])) AS Pvt
ORDER BY Field1, Col