我有一种情况,我正在尝试使用相关子查询,但遇到了 Oracle 中的嵌套限制。我可能错过了 Oracle 的另一个特性,所以我想我会在这里发布这个问题。有谁知道如何在不遇到此嵌套限制的情况下重写以下 SQL,而且还要保持在以下约束范围内?
约束:
- 只能修改 IN 子句中的 SQL(由于我无法控制的限制)
- 如图所示,父查询中的过滤需要在聚合发生之前应用于聚合子查询。
- 应用父过滤器后,在 colB 的聚合上过滤掉 0
下面的代码显示了我在遇到 Oracle 限制之前的尝试。另外,我使用的 Oracle 版本是 11.2.0.2。任何帮助,将不胜感激。谢谢!
SELECT
*
FROM
table1 t1
WHERE
t1.colA BETWEEN XXXX AND XXXX
AND t1.pk_id IN (
SELECT
t2.pk_id
FROM (
SELECT
t3.pk_id,
SUM(t3.amt) OVER (PARTITION BY t3.colB) amt
FROM table1 t3
WHERE t3.colA = t1.colA
) t2
WHERE
t2.amt <> 0
)
以下是运行上述 SQL 时我正在寻找的一些示例输入/输出:
Sample table1:
-----------------------------
| pk_id | colA | colB | amt |
-----------------------------
| 1 | 1 | A | 2 |
| 2 | 1 | A | -1 |
| 3 | 1 | B | 1 |
| 4 | 2 | B | 1 |
| 5 | 2 | A | -2 |
| 6 | 2 | A | 1 |
| 7 | 3 | A | 1 |
t3.colB 与 t1.colA 在 1 和 2 之间的 SUM 结果:
---------------
| pk_id | amt |
---------------
| 1 | 0 |
| 2 | 0 |
| 3 | 2 |
| 4 | 2 |
| 5 | 0 |
| 6 | 0 |
带有 t1.colA BETWEEN 1 和 2 的 IN 子句的子查询结果:
---------
| pk_id |
---------
| 3 |
| 4 |
t1.colA BETWEEN 1 和 2 的顶级查询结果:
-----------------------------
| pk_id | colA | colB | amt |
-----------------------------
| 3 | 1 | B | 1 |
| 4 | 2 | B | 1 |
在完成了提供的一些答案之后,我有一种方法可以通过一个简单的 CASE 语句来避免 Oracle 中的嵌套限制:
SELECT
*
FROM
table1 t1
WHERE
t1.colA BETWEEN 1 AND 2
AND t1.pk_id IN (
SELECT
CASE
WHEN SUM(t2.amt) OVER (PARTITION BY t2.colB) <> 0 THEN t2.pk_id
ELSE NULL
END
FROM table1 t2
WHERE t2.colA = t1.colA
)
不幸的是,这暴露了真正的问题。因为这是一个子查询,所以我一次只能遍历 t1.colA 范围的一个值。这似乎使得无法在子查询中执行该范围内的分析和。因为我只能修改 IN 子句中的 SQL,所以我看不到这个问题的解决方案。如果有人有任何建议,请告诉我。谢谢。