选择 PL/SQL 中两个非空列值之间的行集

Posted

技术标签:

【中文标题】选择 PL/SQL 中两个非空列值之间的行集【英文标题】:SELECT set of rows between two non-null column values in PL/SQL 【发布时间】:2017-09-08 02:04:44 【问题描述】:

我正在寻找一种有效的方法来从表中选择一组行,对 SET 执行一些检查(如计数),然后移动到下一组行。

行选择的标准是获取两行之间的所有行,这些行在一列中有一些非空值。

例如,在下表中,我有一列“PACKAGE_ID”。第一条记录的 ID 为 1A,接下来的 2 条记录没有任何 ID - 意味着它们是 1A 包的一部分。

在这个特定的例子中,我想获得 3 个不同的 SETS

1st set : PRODUCT ID 34, 23, 14
2nd set : PRODUCT ID 48
3rd set : PRODUCT ID 75, 11
╔═════════════════════════════════════════════════════════════════╗
║ PRODUCT_ID             PACKAGE_ID       SORT_SEQUENCE           ║
╠═════════════════════════════════════════════════════════════════╣
║ ---------------------- ----------       ----------------------  ║
║ 34                     1A               1001                    ║
║ 23                     (null)           1002                    ║
║ 14                     (null)           1003                    ║
║ 48                     2B               1004                    ║
║ 75                     3C               1005                    ║
║ 11                     (null)           1006                    ║
╚═════════════════════════════════════════════════════════════════╝

我认为的一种方法是在 CURSOR 中使用 LAG/LEAD 函数并按顺序选择行,一旦发现下一个非空值,在移至下一行之前对前一行执行操作。

但是,我想知道是否有更好的方法来执行 SETS 上的逻辑而不是逐行执行?任何建议/方向将不胜感激。

【问题讨论】:

Gordon 已经为您的通用问题陈述提供了一个有效且通用的解决方案。您正在对组的行执行什么“操作”以及您的 Oracle 版本是什么(由select * from v$version 报告)会很有趣。例如,12.1 版中引入的match_recognize 子句可能会快速完成您的行操作 - 甚至比分析函数解决方案更快。 (但仅适用于 Oracle 12.1 及更高版本!) 不,我在 Oracle 10g 上,所以不能使用更高版本中引入的任何东西。我需要根据集合对其中一个线圈求和,然后根据某些规则将它们分组为单个包。 【参考方案1】:

使用累积总和/计数来分配集合:

select t.*,
       count(package_id) over (order by sort_sequence) as set_id
from t;

count() 计算每一行的非 NULL 值的数量。这就是您要查找的集合 ID。

【讨论】:

是的,我可以在这些 set_ids 的基础上建立逻辑。谢谢戈登!

以上是关于选择 PL/SQL 中两个非空列值之间的行集的主要内容,如果未能解决你的问题,请参考以下文章

左连接 ON 非空列不能选择非空列

SQL Server:选择 4 个非空列并将它们连接起来

在一列中获取火花数据帧的所有非空列

Scala DataFrame,将非空列的值复制到新列中

如何将一个表与另一个表连接,然后计算非空列并将它们按另外两个字段分组?

如何根据另一列的值创建空列或非空列?