具有分析功能的oracle转置[重复]

Posted

技术标签:

【中文标题】具有分析功能的oracle转置[重复]【英文标题】:oracle transposing with analytical function [duplicate] 【发布时间】:2018-01-09 07:12:32 【问题描述】:

我正在转置表中的键值对并遇到问题。 我正在使用Oracle 12C database。 测试数据如下所示。表是tab1

 +---------------------------+
 | Name | VAL  |  ID | grp_id|
 +---------------------------+
 |   a  |   3  |  1  | 1     |
 |   b  |   5  |  2  | 1     |
 |   c  |   8  |  3  | 1     |
 |   c  |   9  |  4  | 2     |
 +---------------------------+ 

我的预期结果是

 +-------------------------+
 | grp_id|   a  |   b  | c |
 +-------------------------+
 |   1   |   3  |   5  | 8 | 
 |   2   | null | null | 9 |  
 +-------------------------+

到目前为止我所做的是

with t as(
select row_number() over (partition by grp_id order by grp_id) rn,
name,
grp_id,
lead(val,0) over (partition by grp_id order by grp_id) as a,
lead(val,1) over (partition by grp_id order by grp_id) as b,
lead(val,2) over (partition by grp_id order by grp_id) as c
from tab1 where grp_id  in (1,2) and name in ('a', 'b','c')
)
select grp_id,a,b,c from t where rn=1;

当数据一致并且所有grp_id-s 键值对都相同时,此查询工作正常,但如果某个grp_id 缺少某些键,我会得到如下结果错了,不是我所期望的

 +----------------------------+
 | grp_id|   a  |   b  | c    |
 +----------------------------+
 |   1   |   3  |   5  | 8    | 
 |   2   |   9  | null | null |  
 +----------------------------+

如何改进查询以使其正常工作?我想避免使用pivot

【问题讨论】:

为什么要避开pivot?另外:abc 是唯一的名字吗,或者还有其他名字吗?如果还有其他人,他们是提前知道的,还是只通过先查看数据? (而且,你为什么要这样做——尤其是为什么在 SQL 中?当需要这样做时,实际上并不经常这样做,它通常在报告层中完成,而不是在 SQL 中。) @mathguy 我不喜欢pivot。可以有更多的名字。因此,当这个问题解决后,我将动态获取所有名称,并使用动态 sql 执行它。这需要在SQL中完成,就是这样。 如果需要使用动态SQL,显然in SQL不会这样做;这需要 PL/SQL,这与 SQL 完全不同(即使与 SQL 紧密集成)。这也有助于了解为什么您不喜欢pivot。如果你能学会如何正确使用它会更好;这并不难,真的。如果您需要使用旋转的“旧样式”(如 Gordon 的回答)编写动态 SQL 代码,上帝会帮助您。用pivot 写就够糟糕了,没有它就更糟了。祝你好运! @mathguy 对我来说,使用数据透视查询变得不必要地复杂。特别是当有很多不同的键时。是的,我知道 SQL 和 PL/SQL 的范围 :) 谢谢。 【参考方案1】:

我会使用条件聚合来做到这一点:

select grp_id,
       max(case when name = 'a' then val end) as a,
       max(case when name = 'b' then val end) as b,
       max(case when name = 'c' then val end) as c
from tab1
group by grp_id;

grp_id 已经定义,所以我认为不需要分析函数。

【讨论】:

首先想到的是分析,却错过了这种转置方式。谢谢你。在接受这个作为答案之前,我会等待也许有人会建议使用lead 进行改进。如果可以通过分析函数获得我的预期结果,那仍然很有趣。这对我来说很有挑战性:) @arminrock - 没有“领先的改进”;旋转与分析函数完全无关。 Gordon 在这里展示的是在 Oracle 引入 pivot 运算符以使每个人的生活更轻松之前完成旋转的方式。你可以用谷歌搜索“pivoting in Oracle 10”(即使在 Stack Overflow 上也必须有 100 个线程),你会相信这一点。 @mathguy 伙计,放轻松,这个问题不是生死攸关的问题,编码很有趣,不要限制自己,也许有人会建议,也许它会比 case 和 pivot 表现得更好: )请删除重复的问题来自不同的角度。然而,您在这篇文章中进行了如此多的活动,但没有真正的建议或代码 sn-p 或证明分析不适用于转置:) @arminrock - 解决问题的正确方法是使用 PIVOT,或者在早期版本的 Oracle 中,就像 Gordon 所展示的那样。另一个评价很高的论坛成员(不是我!)发布了与 Gordon 完全相同的答案,然后将其删除——这完全是正确的做法。如果我要发布一些内容,那将是 Gordon 发布的内容,那我为什么要发布呢?然后 - 问题是完全重复的;如果有人找到了一个很酷的解决方案,他们应该在那里发布他们的答案,而不是在这里。反对前请先熟悉 *** 规则。 @arminrock - 顺便说一句:我不赞成戈登的回答(我没有)的原因是我认为他的行为是不正确的。他和我一样清楚这是重复的,他应该做我所做的:关闭重复的问题,而不是第 100 次发布相同的答案。

以上是关于具有分析功能的oracle转置[重复]的主要内容,如果未能解决你的问题,请参考以下文章

将行转置为具有条件的列[重复]

选择具有自定义金额 Oracle 的重复行

SQL转置表 - sqlserver [重复]

在Oracle中选择具有最近日期和时间的记录[重复]

Oracle始终获取具有标识的插入行的ID [重复]

如何连接具有选择性重复记录的表? (oracle10g)