【问题标题】:Get rows of table as columns in second table获取表的行作为第二个表中的列
【发布时间】:2015-07-09 14:48:50
【问题描述】:

如果之前有人问过这个问题,我提前道歉。

我有两张桌子。表一有三列CustomerID, SequenceNum, Value,表二有大量列。我想用表一的值逐列而不是逐行填充表二的列。

一个例子:

------------------------------------
| CustomerID | SequenceNum | Value |
------------------------------------
|      1     |      1      |   A   |
------------------------------------
|      1     |      2      |   B   |
------------------------------------
|      1     |      3      |   C   |
------------------------------------
|      2     |      1      |   Q   |
------------------------------------
|      2     |      2      |   R   |
------------------------------------
|      3     |      1      |   X   |
------------------------------------

变成

---------------------------------------------------------------------
| CustomerID | PrimaryVal | OtherVal1 | OtherVal2 | OtherVal3 | ... |
---------------------------------------------------------------------
|      1     |      A     |     B     |     C     |    NULL   | ... |
---------------------------------------------------------------------
|      2     |      Q     |     R     |    NULL   |    NULL   | ... |
----------------------------------------------------------------------
|      3     |      X     |    NULL   |    NULL   |    NULL   | ... |
---------------------------------------------------------------------

本质上。表一中的每个唯一 CustomerID 在表二中将有一行。特定CustomerID 的每个SequenceNum 将填写表二中PrimaryVal, OtherVal1, OtherVal2, etc. 下的一列。 SequenceNum 等于 1 的行将填充 PrimaryVal 字段,2-18(最大序列长度为 18)将填充 OtherVal#

我看到的主要问题是序列中值的数量可变。有些序列可能只包含 1 行,有些会填满所有 18 个点,以及介于两者之间的任何内容。

任何有关如何解决此问题的建议将不胜感激。谢谢。

【问题讨论】:

  • pivot 是你的朋友我的朋友...
  • @MikeMiller 检查我最近的编辑。如果序列的大小可变,我看不出如何使用枢轴
  • 您是否尝试过类似 select customerID, Pivoted.* from Customer pivot( Value for sequencenum in (1,2,3,4,5,6, upto 18)) as Pivoted 之类的方法
  • @MikeMiller 如果 SequenceNum 在某个 CustomerID 上仅变为 5,那不会因为 6-18 不存在而导致错误吗?
  • 我想你只会得到空值,我现在不在 SQL 框前面,用 SQLFiddle 试试吧

标签: sql sql-server database sql-server-2012


【解决方案1】:

鉴于您知道它最多 18 列,我会采用正常的枢轴路线。

select customerID, Pivoted.*
 from Customer
 pivot( Value for sequencenum in (1,2,3,4,5,6, upto 18)) as Pivoted

我在这里一直很懒惰,没有为列添加别名,但如果需要,您可以。

【讨论】:

  • 如果列不是动态的,则同意使用固定。您只需要添加一个聚合并转义列名,即pivot( Max(Value) for sequencenum in ([1],[2],[3],[4],[5],[6] ... ))
【解决方案2】:

这可以通过动态枢轴来完成。第一个STUFF Select(或任何其他GROUP_CONCAT hack)用于确定所需的列(基于SequenceNum 的值),然后将其应用于动态透视,然后将值分配给这些列。

您需要在数据透视期间对聚合发表意见(我使用过Min),但如果没有重复的CustomerId, SequenceNum 元组,这是一个相当随意的选择:

DECLARE 
  @cols AS NVARCHAR(MAX),
  @query  AS NVARCHAR(MAX);

SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(SequenceNum) 
            FROM Table1
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'');

set @query = N'SELECT CustomerID, ' + @cols + N' from
            Table1 
            pivot 
            (
                min(Value)
                for SequenceNum in (' + @cols + N')
            ) p ';
 execute(@query);

SqlFiddle here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-10-23
    • 2020-12-28
    • 2022-11-25
    • 1970-01-01
    • 2020-04-08
    • 2017-02-11
    • 2015-01-18
    • 1970-01-01
    相关资源
    最近更新 更多