我遇到的情况是我试图使用相关的子查询,但是我遇到了Oracle中的嵌套限制。我可能会错过Oracle的另一个功能,所以我想我会在这里发布这个问题。有没有人知道如何在不遇到这个嵌套限制的情况下重写下面的SQL,但是还要保持在下面的约束范围内?
约束:
以下代码显示了我在尝试此操作之前遇到的Oracle限制。此外,Oracle版本I是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 |
使用t1.colA BETWEEN 1和2时的SUM与t3.colB的结果:
---------------
| pk_id | amt |
---------------
| 1 | 0 |
| 2 | 0 |
| 3 | 2 |
| 4 | 2 |
| 5 | 0 |
| 6 | 0 |
IN子句的子查询结果,带有t1.colA BETWEEN 1和2:
---------
| 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,所以我看不到这个问题的解决方案。如果有人有任何建议,请告诉我。感谢。
答案 0 :(得分:0)
如果您知道值之间的内容并且可以在子查询中使用它们,那么您可以将其添加到子查询中:
SELECT
*
FROM
table1 t1
WHERE
t1.colA BETWEEN 1 AND 2
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 BETWEEN 1 AND 2
) t2
WHERE
t2.amt <> 0
)
答案 1 :(得分:0)
您可以像这样重写您的查询:
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, t3.ColA, SUM(t3.amt) as amt
FROM table1 t3
group by t3.pk_id, t3.ColA
having sum(t3.amt) > 0
) t2
WHERE t2.colA = t1.colA
)
从这里开始,您可以将其重写为:
select t1.*
from table1 t1 join
(SELECT t3.pk_id, t3.ColA, SUM(t3.amt) as amt
FROM table1 t3
group by t3.pk_id, t3.ColA
having sum(t3.amt) > 0
) t2
on t1.pk_id = t2.pk_id and t1.ColA = t3.ColA
WHERE t1.colA BETWEEN XXXX AND XXXX