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
或
使用aggregation
和case
也可以做到,
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 服务器的主要内容,如果未能解决你的问题,请参考以下文章