Oracle 数据透视转换到 SQL 服务器

Posted

技术标签:

【中文标题】Oracle 数据透视转换到 SQL 服务器【英文标题】:Oracle pivot transform to SQL server 【发布时间】:2020-10-16 10:29:13 【问题描述】:

简短的问题,对 SQL server 不太熟悉,但我在 oracle sql server 中有多个聚合的查询。

多重聚合的sql server等效查询是什么?

Oracle 代码:

[SELECT *
   FROM (SELECT d.loc_area,
                d.loc_rack,
                d.loc_height,
                d.loc_place,
                d.locvrc,
                row_number() OVER(PARTITION BY d.loc_area, d.loc_rack, d.loc_place
                                   ORDER BY d.loc_height) rn_pivot
           FROM (select locvrc,
                        SUBSTR(stoloc, 0, 2) loc_area,
                        SUBSTR(stoloc, 4, 2) loc_rack,
                        SUBSTR(stoloc, 6, 1) loc_place,
                        SUBSTR(stoloc, -2) loc_height
                   FROM locls) d)
  PIVOT (MAX(loc_height) AS EXT, MIN(locvrc) AS UNIQ FOR rn_pivot IN ('1' AS HEIGHT_1, '2' AS HEIGHT_2, '3' AS HEIGHT_3, '4' AS HEIGHT_4))
  ORDER BY LOC_AREA,
        LOC_RACK,
        LOC_PLACE]

SQL 服务器:

SELECT *
   FROM (SELECT d.loc_area,
                d.loc_rack,
                d.loc_height,
                d.loc_place,
                d.locvrc,
                row_number() OVER(PARTITION BY d.loc_area, d.loc_rack, d.loc_place
                                   ORDER BY d.loc_height) rn_pivot
           FROM (select locvrc,
                        SUBSTRing(stoloc, 0, 2) loc_area,
                        SUBSTRing(stoloc, 4, 2) loc_rack,
                        SUBSTRing(stoloc, 6, 1) loc_place,
                        right(stoloc, 2) loc_height
                   FROM locls) d) A
  PIVOT (MAX(loc_height) FOR rn_pivot IN ([1],[2],[3],[4])) P1 

这工作正常,但我还需要另一个聚合 |(MIN(locvrc)| 也

提前谢谢你!

溴 一月

/编辑,

原表:

 Stoloc          locvrc
 5D-32A-00       699787
 5D-32A-10       439567
 5D-32A-20       429456
 5D-32A-30       122172
 5D-32B-00       328311
 5D-32B-10       247422
 5D-32B-20       133244
 5D-32B-30       464978

子字符串后的表格:

loc_area loc_rack loc_place loc_height locvrc
 5D         32       A        00       699787
 5D         32       A        10       439567
 5D         32       A        20       429456
 5D         32       A        30       122172
 5D         32       B        00       328311
 5D         32       B        10       247422
 5D         32       B        20       133244
 5D         32       B        30       464978

我对 Oracle 的看法是:

loc_area loc_rack loc_place Height1 Uniq1   Height2 Uniq2   Height3 Uniq3 Height4 Unique4
5D       32        A         00     699787    10    439567    20    429456    30   122172
5D       32        B         00     328311    10    247422    20    133244    30   464978

因此,从原始表格中,stoloc 将被切割成不同的列。在这一行之后,区域、机架、位置和它们在一行中的高度和 locvrc。我已经在 Oracle 数据库中完成了这项工作,但不知道如何在 SQl 服务器中完成。不需要这种解决方案,任何人都可以。

【问题讨论】:

提供示例数据、期望的结果以及代码应该做什么的清晰解释。 添加了更多信息。让我知道是否仍然缺乏。 -一月 示例表中的列名与查询中的列(stoloc)不符 我知道这是一团糟。我需要编辑全新的帖子以便更容易提供帮助。认为会有简单的解决方案,比如“在此处添加”:) @Jan00,已更新,现在应该给出正确的结果 :) 【参考方案1】:

您可能会觉得这很奇怪,但据我所知,这是我们在 SQL server 中可以做到的。

我们需要通过附加任何内容为相同的数据透视列创建另一个维度,并将其放入PIVOT 子句中。

如您所见,我已添加 1 并创建另一列用于 locvrc

SELECT *
   FROM (SELECT d.loc_area,
                d.loc_rack,
                d.loc_height,
                d.loc_place,
                d.locvrc,
                row_number() OVER(PARTITION BY d.loc_area, d.loc_rack, d.loc_place
                                   ORDER BY d.loc_height) rn_pivot,
                cast(row_number() OVER(PARTITION BY d.loc_area, d.loc_rack, d.loc_place
                                   ORDER BY d.loc_height) as varchar) + '1' rn_pivot_locvrc
           FROM (select locvrc,
                        SUBSTRing(stoloc, 0, 2) loc_area,
                        SUBSTRing(stoloc, 4, 2) loc_rack,
                        SUBSTRing(stoloc, 6, 1) loc_place,
                        right(stoloc, 2) loc_height
                   FROM locls) d) A
  PIVOT (MAX(loc_height) FOR rn_pivot IN ([1],[2],[3],[4])) P1
  PIVOT (MAX(locvrc) FOR rn_pivot_locvrc IN ([11],[21],[31],[41])) P2

附:我的目的是告诉你如何PIVOT 多个列,但不幸的是我当然无法验证结果集。

编辑:- 使用 Op 的实际数据更新查询

SELECT loc_area,loc_rack,loc_place
      ,max([1]) as height_1
      ,max([11]) as unique_1
      ,max([2]) as height_2
      ,max([21]) as unique_2
      ,max([3]) as height_3
      ,max([31]) as unique_3
      ,max([4]) as height_4
      ,max([41]) as unique_4
   FROM (SELECT d.loc_area,
                d.loc_rack,
                d.loc_height,
                d.loc_place,
                d.locvrc,
                row_number() OVER(PARTITION BY d.loc_area, d.loc_rack, d.loc_place
                                   ORDER BY d.loc_height) rn_pivot,
                cast(row_number() OVER(PARTITION BY d.loc_area, d.loc_rack, d.loc_place
                                   ORDER BY d.loc_height) as varchar) + '1' rn_pivot_locvrc
           FROM (select locvrc,
                        SUBSTRing(stoloc, 0, 2) loc_area,
                        SUBSTRing(stoloc, 4, 2) loc_rack,
                        SUBSTRing(stoloc, 6, 1) loc_place,
                        right(stoloc, 2) loc_height
                   FROM locls) d) A
  PIVOT (MAX(loc_height) FOR rn_pivot IN ([1],[2],[3],[4])) P1
  PIVOT (MAX(locvrc) FOR rn_pivot_locvrc IN ([11],[21],[31],[41])) P2
group by loc_area,loc_rack,loc_place

使用aggregationcase也可以做到,

SELECT loc_area,loc_rack,loc_place
      ,max(case when rn = 1 then loc_height end) height_1
      ,max(case when rn = 1 then locvrc end) unique_1
      ,max(case when rn = 2 then loc_height end) height_2
      ,max(case when rn = 2 then locvrc end) unique_2
      ,max(case when rn = 3 then loc_height end) height_3
      ,max(case when rn = 3 then locvrc end) unique_3
      ,max(case when rn = 4 then loc_height end) height_4
      ,max(case when rn = 4 then locvrc end) unique_4
   FROM (SELECT d.loc_area,
                d.loc_rack,
                d.loc_height,
                d.loc_place,
                d.locvrc,
                row_number() OVER(PARTITION BY d.loc_area, d.loc_rack, d.loc_place
                                   ORDER BY d.loc_height) rn
           FROM (select locvrc,
                        SUBSTRing(stoloc, 0, 2) loc_area,
                        SUBSTRing(stoloc, 4, 2) loc_rack,
                        SUBSTRing(stoloc, 6, 1) loc_place,
                        right(stoloc, 2) loc_height
                   FROM locls) d) A
group by loc_area,loc_rack,loc_place;

【讨论】:

是的,您是对的,因为您有其他列,例如 d.loc_area,d.loc_rack,d.loc_place,您没有进行旋转,它可能会影响结果集。而且我在您的原始查询中没有看到columnA ColumnB 感谢 Sujitmohanty30 的回复。能够运行查询,正如您提到的无法验证结果并且它不完全正确。不过要朝着正确的方向发展。 @Jan00,我意识到我刚刚纠正的查询中有一个错误,这可能是原因,但我不确定 哦,我自己也看到了,也更正了,但事实并非如此。但我会更好地编辑帖子,以便更容易提供帮助,我知道在示例和查询中使用不同的列名有点混乱。 我知道现在引入额外维度也会改变输出,为了解决它,我们需要聚合最终结果。我已经使用您发送的示例设置了查询。如果对你有帮助,你可以看看。 db<>fiddle example

以上是关于Oracle 数据透视转换到 SQL 服务器的主要内容,如果未能解决你的问题,请参考以下文章

在 Oracle SQL 中将数据透视表转换为平面表

Oracle SQL 数据透视表从一列变为两列

将数据透视到新的列名 - Oracle SQL

oracle 数据透视表

Excle数据透透视表如何删除数据透视表

有没有办法将“%”符号添加到我在 Oracle SQL 中的透视结果中并将它们转换为 to_char