【问题标题】:Pivot multiple columns with a column value repeats for each new column枢轴多个列,每个新列的列值重复
【发布时间】:2018-04-11 02:21:11
【问题描述】:

我需要你的帮助来为以下输出构建一个 sql 查询/sp。

我的表格包含以下数据:

我想生成如下输出:

请注意,这里的 FieldName 不只是表中的四个,它会有所不同。

在数据下方查找:

CREATE TABLE #Results
(
    FieldName  nvarchar(50),
    FieldValue  nvarchar(50),
    RecordStaus int
); 

INSERT INTO #Results(FieldName,FieldValue,RecordStaus)
VALUES ('Coverage',NULL,1)
      ,('Premium',NULL,2)
      ,('F1',100,1)
      ,('F2',100,1)
      ,('Coverage',200,1)
      ,('Premium',10,1)
      ,('F1',50,1)
      ,('F2',NULL,3)
      ,('Coverage',300,1)
      ,('Premium',45,1)
      ,('F1',24,1)
      ,('F2',NULL,1)
      ,('Coverage',450,3)
      ,('Premium',12,3)
      ,('F1',50,1)
      ,('F2',NULL,1);

【问题讨论】:

  • 您是否有将值按行分组的列?

标签: sql sql-server tsql pivot pivot-table


【解决方案1】:

你可以试试这个:

CREATE TABLE #Results
(
id int identity(1,1),
FieldName  nvarchar(50),
FieldValue  nvarchar(50),
RecordStaus int
); 

INSERT INTO #Results(FieldName,FieldValue,RecordStaus)
VALUES ('Coverage',NULL,1)
,('Premium',NULL,2)
,('F1',100,1)
,('F2',100,1)
,('Coverage',200,1)
,('Premium',10,1)
,('F1',50,1)
,('F2',NULL,3)
,('Coverage',300,1)
,('Premium',45,1)
,('F1',24,1)
,('F2',NULL,1)
,('Coverage',450,3)
,('Premium',12,3)
,('F1',50,1)
,('F2',NULL,1);


DECLARE @DynamicTSQLStatement NVARCHAR(MAX)
       ,@Columns NVARCHAR(MAX);


SELECT @Columns = STUFF
(
    (

        SELECT *
        FROM
        (
            SELECT DISTINCT ',[' + CAST([FieldName] AS NVARCHAR(50)) + ']'
            FROM #Results
            UNION
            SELECT DISTINCT ',[' + CAST([FieldName] + '_RecordStaus' AS NVARCHAR(50)) + ']'
            FROM #Results
        ) DS ([FieldName])
        FOR XML PATH(''), TYPE

    ).value('.', 'VARCHAR(MAX)')
    ,1
    ,1
    ,''
);


SET @DynamicTSQLStatement = N'
SELECT *
FROM
(
    SELECT [FieldName]
           + CASE WHEN [Column] = ''RecordStaus'' THEN ''_RecordStaus'' ELSE '''' END AS [FieldName]
          ,[rowID]
          ,[Value]
    FROM 
    ( 
        SELECT [FieldName]
              ,[FieldValue]
              ,CAST([RecordStaus] AS NVARCHAR(50))
              ,ROW_NUMBER() OVER (PARTITION BY [FieldName] ORDER BY [id]) 
        FROM #Results
    ) DS ([FieldName], [FieldValue], [RecordStaus], [rowID])
    UNPIVOT
    (
        [Value] FOR [Column] IN ([FieldValue], [RecordStaus])
    ) UNPVT
) ReadyForPivot
PIVOT
(
    MAX([Value]) FOR [FieldName] IN (' + @Columns +')
) PVT;
';

EXEC sp_executesql @DynamicTSQLStatement;

DROP TABLE #Results;

几点说明:

  • 我添加了id 列,以便了解哪一行的值/在您的实际情况下,您可以使用其他方式或SELECT 1ROW_NUMBER 函数中使用排序;您需要这样的方式来确保结果是确定性的;
  • 我正在使用动态 SQL 以使查询适用于 FildName 列的各种值 - 如果您需要列的特定顺序,可以使用 FOR XML 子句中的 ORDER BY 子句来执行此操作。例如:

    SELECT @Columns = STUFF
    (
        (
    
            SELECT *
            FROM
            (
                SELECT DISTINCT ',[' + CAST([FieldName] AS NVARCHAR(50)) + ']'
                FROM #Results
                UNION
                SELECT DISTINCT ',[' + CAST([FieldName] + '_RecordStaus' AS NVARCHAR(50)) + ']'
                FROM #Results
            ) DS ([FieldName])
            ORDER BY [FieldName] DESC -- you can order the columns as you like
            FOR XML PATH(''), TYPE
    
        ).value('.', 'VARCHAR(MAX)')
        ,1
        ,1
        ,''
    );
    

    然后在动态SQL中添加@columns变量值:

    SET @DynamicTSQLStatement = N'
    SELECT' + @columns + ' ...
    

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-03-31
    • 2012-09-23
    • 1970-01-01
    • 2017-03-02
    • 2017-08-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多