【问题标题】:Unpivoting multiple columns取消旋转多个列
【发布时间】:2014-07-26 17:31:43
【问题描述】:

我在 SQL Server 2014 中有一个名为 anotes 的表,其中包含以下数据

我想将此数据添加到另一个名为 final 的表中

ID      Notes      NoteDate

text1, text2, text3, text4 进入决赛桌的Notes 列,Notedate1,notedate2,notedate3,notedate4 进入Notedate 列。

我尝试先用注释对数据进行反透视:

select createdid, temp
from (select createdid,text1,text2,text3,text4 from anotes) p
unpivot
(temp for note in(text1,text2,text3,text4)) as unpvt
order by createdid

这给了我正确的结果:

然后对于日期部分,我使用了另一个非透视查询:

select createdid,temp2
from (select createdid,notedate1,notedate2,notedate3,notedate4 from anotes) p
unpivot (temp2 for notedate in(notedate1,notedate2,notedate3,notedate4)) as unpvt2

这也给了我正确的结果:

现在我想将此数据添加到我的最终表格中。

我尝试了以下查询,结果是交叉连接:(

select a.createdid, a.temp, b.temp2
from (select createdid, temp
      from (select createdid,text1,text2,text3,text4 from anotes) p
      unpivot
      (temp for note in(text1,text2,text3,text4)) as unpvt) a inner join (select createdid,temp2
from (select createdid,notedate1,notedate2,notedate3,notedate4 from anotes) p
unpivot (temp2 for notedate in(notedate1,notedate2,notedate3,notedate4)) as unpvt) b on a.createdid=b.createdid

输出如下:

有什么方法可以同时对两列进行反透视?

或者使用两个选择查询将该数据添加到我的最终表格中?

提前致谢!

【问题讨论】:

  • 试试this blog 或者只搜索SQL Multiple Unpivot
  • 感谢@AHiggins 的链接,工作就像一个魅力!

标签: sql tsql unpivot sql-server-2014


【解决方案1】:

我想说最简洁,也可能是最有效的取消透视多列的方法是使用CROSS APPLYtable valued constructor

SELECT  t.CreatedID, upvt.Text, upvt.NoteDate
FROM    anotes t
        CROSS APPLY
        (VALUES
            (Text1, NoteDate1),
            (Text2, NoteDate2),
            (Text3, NoteDate3),
            (Text4, NoteDate4),
            (Text5, NoteDate5),
            (Text6, NoteDate6),
            (Text7, NoteDate7)
        ) upvt (Text, NoteDate);

Simplified Example on SQL Fiddle


附录

我发现这个概念很难解释,但我会尝试。表值构造器只是动态定义表的一种方式,所以

SELECT  *
FROM    (VALUES (1, 1), (2, 2)) t (a, b);

将使用别名和数据创建一个表:

a   b
------
1   1
2   2

因此,当您在 APPLY 中使用它时,您可以访问所有外部列,因此只需使用正确的值对(即 text1 和 date1)定义您构建的表。

【讨论】:

  • 哇,我想你赢了。那确实表现最好。现在我只需要尝试弄清楚它是如何工作的。
【解决方案2】:

使用@AHiggins 提到的上述链接

以下是我的最终查询!

select createdid,temp,temp2
from (select createdid,text1,text2,text3,text4,text5,text6,text7,notedate1,notedate2,notedate3,notedate4,notedate5,notedate6,notedate7 from anotes) main
      unpivot
      (temp for notes in(text1,text2,text3,text4,text5,text6,text7)) notes
unpivot (temp2 for notedate in(notedate1,notedate2,notedate3,notedate4,notedate5,notedate6,notedate7)) Dates
where RIGHT(notes,1)=RIGHT(notedate,1)

【讨论】:

  • 太棒了!将此问题标记为已回答(查找您自己的答案旁边的复选框),以便系统识别该问题已得到解决,祝您好运!
【解决方案3】:

将每个查询视为一个表,并根据 createdid 和 fieldid(字段名称的数字部分)将它们连接在一起。

select x.createdid, x.textValue, y.dateValue
from
(
    select createdid, substring(note, 5, len(note)) fieldId, textValue
    from (select createdid,text1,text2,text3,text4 from anotes) p
    unpivot
    (textValue for note in(text1,text2,text3,text4)) as unpvt
)x
join
(
    select createdid, substring(notedate, 9, len(notedate)) fieldId, dateValue
    from (select createdid,notedate1,notedate2,notedate3,notedate4 from anotes) p
    unpivot (dateValue for notedate in(notedate1,notedate2,notedate3,notedate4)) as unpvt2
) y on x.fieldId = y.fieldId and x.createdid = y.createdid
order by x.createdid, x.fieldId

如果您有太多列并且字段名称的最右边数字重复(例如 text1 和 text11),则给出的其他答案将不起作用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多