【问题标题】:SQL Query - Almost pivot table-like?SQL 查询 - 几乎类似于数据透视表?
【发布时间】:2012-03-29 20:48:22
【问题描述】:

这里还有一个关于 SQL 场景的愚蠢问题。

给定数据,例如:

FieldKey    DocumentKey FieldId FieldValue
1   00001c55-aab3-4df8-a07e-8eac162fa075    TITLE   Mass Import 18355
2   00001c55-aab3-4df8-a07e-8eac162fa075    1   00001c55-aab3-4df8-a07e-8eac162fa075
3   00001c55-aab3-4df8-a07e-8eac162fa075    2   9F-2F-CF-76-27-E7-5B-C9-27-CE-23-45-68-3F-E2-89
4   00001c55-aab3-4df8-a07e-8eac162fa075    3   18355
5   00001c55-aab3-4df8-a07e-8eac162fa075    4   94-3C-84-B1-6A-AA-FD-25-F1-C0-D2-43-CD-D3-57-D6
6   00001c55-aab3-4df8-a07e-8eac162fa075    5   Created by C# mass import
7   00002205-00D3-4495-B65A-A7B1FD2AE7F2    TITLE   Mass Import 1494780
8   00002205-00D3-4495-B65A-A7B1FD2AE7F2    1   00002205-00D3-4495-B65A-A7B1FD2AE7F2
9   00002205-00D3-4495-B65A-A7B1FD2AE7F2    2   870386312
10  00002205-00D3-4495-B65A-A7B1FD2AE7F2    3   1494780
11  00002205-00D3-4495-B65A-A7B1FD2AE7F2    4   -1929051324
13  00002342-6de0-4110-b576-fd32f96b2858    TITLE   Mass Import 387008
14  00002342-6de0-4110-b576-fd32f96b2858    1   00002342-6de0-4110-b576-fd32f96b2858
15  00002342-6de0-4110-b576-fd32f96b2858    2   B0-CB-DF-ED-48-DC-C4-E8-B0-6F-1B-1D-81-2D-6D-51
16  00002342-6de0-4110-b576-fd32f96b2858    3   387008

带表结构:

[FieldKey] [bigint] IDENTITY(1,1) NOT NULL,
[DocumentKey] [char](36) NOT NULL,
[FieldId] [varchar](10) NOT NULL,
[FieldValue] [varchar](255) NOT NULL

水平翻转这些数据的最佳方法是什么?理想情况下:

DocumentKey                             TITLE    1    2    3    4    5
00001c55-aab3-4df8-a07e-8eac162fa075    mytitle  val1 val2 val3 val4 val5
00002205-00D3-4495-B65A-A7B1FD2AE7F2    mytitle2 val6 val7 val8 val9
00002342-6de0-4110-b576-fd32f96b2858    mytitle3 vl10 vl11 vl12

我认为数据透视表可能工作并且它很接近,但问题是我不需要 SQL 数据透视所需的聚合。我只想翻转数据。列数(在我的示例中为 1-5 加上 TITLE)可以在 TITLE 加上 1-30 之间。

也许我只是太密集了,但任何想法都会受到赞赏。

【问题讨论】:

    标签: sql-server pivot


    【解决方案1】:

    我认为您的 PIVOT 是正确的。您将在 value 列上进行聚合。但正如你所说,你将有 1-30 列加上标题列。这需要一个动态的支点

    这是一个建议(仅适用于 SQL Server 2005+):

    测试数据

    CREATE TABLE Table1
    (
        [FieldKey] [bigint] NOT NULL,
        [DocumentKey] [char](36) NOT NULL,
        [FieldId] [varchar](10) NOT NULL,
        [FieldValue] [varchar](255) NOT NULL
    )
    INSERT INTO Table1
    VALUES
        (1,'00001c55-aab3-4df8-a07e-8eac162fa075','TITLE','Mass Import 18355'),
        (2,'00001c55-aab3-4df8-a07e-8eac162fa075','1','00001c55-aab3-4df8-a07e-8eac162fa075'),
        (3,'00001c55-aab3-4df8-a07e-8eac162fa075','2','9F-2F-CF-76-27-E7-5B-C9-27-CE-23-45-68-3F-E2-89'),
        (4,'00001c55-aab3-4df8-a07e-8eac162fa075','3','18355'),
        (5,'00001c55-aab3-4df8-a07e-8eac162fa075','4','94-3C-84-B1-6A-AA-FD-25-F1-C0-D2-43-CD-D3-57-D6'),
        (6,'00001c55-aab3-4df8-a07e-8eac162fa075','5','Created by C# mass import'),
        (7,'00002205-00D3-4495-B65A-A7B1FD2AE7F2','TITLE','Mass Import 1494780'),
        (8,'00002205-00D3-4495-B65A-A7B1FD2AE7F2','1','00002205-00D3-4495-B65A-A7B1FD2AE7F2'),
        (9,'00002205-00D3-4495-B65A-A7B1FD2AE7F2','2','870386312'),
        (10,'00002205-00D3-4495-B65A-A7B1FD2AE7F2','3','1494780'),
        (11,'00002205-00D3-4495-B65A-A7B1FD2AE7F2','4','-1929051324'),
        (13,'00002342-6de0-4110-b576-fd32f96b2858','TITLE','Mass Import 387008'),
        (14,'00002342-6de0-4110-b576-fd32f96b2858','1','00002342-6de0-4110-b576-fd32f96b2858'),
        (15,'00002342-6de0-4110-b576-fd32f96b2858','2','B0-CB-DF-ED-48-DC-C4-E8-B0-6F-1B-1D-81-2D-6D-51'),
        (16,'00002342-6de0-4110-b576-fd32f96b2858','3','387008')
    

    查找唯一列

    DECLARE @cols VARCHAR(MAX)
    ;WITH CTE
    AS
    (
        SELECT
            ROW_NUMBER() OVER(PARTITION BY Table1.FieldId 
                                  ORDER BY Table1.FieldId) AS RowNbr,
            Table1.*
        FROM
            Table1
    )
    SELECT @cols=STUFF
    (
        (
            SELECT 
                ',' +QUOTENAME(CTE.FieldId)
            FROM
                CTE
            WHERE
                CTE.RowNbr=1
            ORDER BY 
                LEN(CTE.FieldId) DESC,
                CTE.FieldId
            FOR XML PATH('')
        )
    ,1,1,'')
    

    我们需要先订购TITLEFOR XML PATH 是连接列。

    动态枢轴

    DECLARE @query NVARCHAR(4000)=
    N'SELECT
        *
    FROM
    (
        SELECT
            Table1.DocumentKey,
            Table1.FieldId,
            Table1.FieldValue
        FROM
            Table1
    ) AS p
    PIVOT
    (
        MAX(FieldValue)
        FOR FieldId IN('+@cols+')
    ) AS p'
    EXECUTE(@query)
    

    自己清理(非必需)

    DROP TABLE Table1
    

    【讨论】:

      【解决方案2】:

      如果您使用的是 SQL Server 2005+,则可以使用 PIVOT 运算符。

      select [DocumentKey], [TITLE], [1], [2], [3], [4], [5] 
      from (select [DocumentKey], FieldId, FieldValue from TableName) t
          pivot (max(FieldValue) for FieldID in ([TITLE], [1], [2], [3], [4], [5])) as pvt
      order by [DocumentKey]
      

      您必须添加额外的列,6 - 30。

      【讨论】:

      • 我不认为 OP 想要一个静态支点。如果列在 1-30 之间变化,则不会考虑这一点。
      • 肯定会 - 添加所有 30 列,如果列不存在,它将只有一个空值。认为问题的要点是“......问题是我不需要 SQL 数据透视所需的聚合。我只想翻转数据。”只需使用 MAX 函数。
      • 两者都是正确的 :) 我们最终可能会有超过 30 列,所以动态性很棒,尽管在短期内是不必要的。
      • 另外,我对枢轴语法的尝试不太正确(因此我要求提示),所以我使用 MAX 函数得到了奇怪的结果。事实证明我真的很近,但距离足够远,它仍然无法正常工作。
      猜你喜欢
      • 2023-03-25
      • 1970-01-01
      • 2019-07-22
      • 2016-06-22
      • 2012-04-07
      • 1970-01-01
      • 1970-01-01
      • 2018-02-09
      • 2014-09-08
      相关资源
      最近更新 更多