Sql Oracle相关子查询嵌套限制是否有解决方法?
我有一种情况,我试图使用相关子查询,但在Oracle中遇到嵌套限制。我可能错过了Oracle的另一个功能,所以我想我应该在这里发布这个问题。有人知道如何重写下面的SQL而不受嵌套限制,但又不受下面的限制吗 限制条件: 由于我无法控制的约束,只能修改in子句中的SQL 如图所示,在聚合发生之前,需要将父查询中的筛选应用于聚合子查询。 应用父筛选器后,在colB聚合上筛选出0 下面的代码显示了我在遇到Oracle限制之前的尝试。另外,我使用的Oracle版本是11.2.0.2。任何帮助都将不胜感激。谢谢Sql Oracle相关子查询嵌套限制是否有解决方法?,sql,oracle,subquery,correlated-subquery,in-subquery,Sql,Oracle,Subquery,Correlated Subquery,In Subquery,我有一种情况,我试图使用相关子查询,但在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
)
t3.colB和t1.colA之和介于1和2之间的结果:
---------------
| pk_id | amt |
---------------
| 1 | 0 |
| 2 | 0 |
| 3 | 2 |
| 4 | 2 |
| 5 | 0 |
| 6 | 0 |
---------
| pk_id |
---------
| 3 |
| 4 |
-----------------------------
| pk_id | colA | colB | amt |
-----------------------------
| 3 | 1 | B | 1 |
| 4 | 2 | B | 1 |
t1.colA介于1和2之间的IN子句的子查询结果:
---------------
| pk_id | amt |
---------------
| 1 | 0 |
| 2 | 0 |
| 3 | 2 |
| 4 | 2 |
| 5 | 0 |
| 6 | 0 |
---------
| pk_id |
---------
| 3 |
| 4 |
-----------------------------
| pk_id | colA | colB | amt |
-----------------------------
| 3 | 1 | B | 1 |
| 4 | 2 | B | 1 |
t1.colA介于1和2之间的顶级查询结果:
---------------
| pk_id | amt |
---------------
| 1 | 0 |
| 2 | 0 |
| 3 | 2 |
| 4 | 2 |
| 5 | 0 |
| 6 | 0 |
---------
| pk_id |
---------
| 3 |
| 4 |
-----------------------------
| pk_id | colA | colB | amt |
-----------------------------
| 3 | 1 | B | 1 |
| 4 | 2 | B | 1 |
在完成了提供的一些答案之后,我有了一种方法,可以通过一个简单的案例陈述来避免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,所以我看不到这个问题的解决方案。如果有人有任何建议,请告诉我。谢谢。如果您知道中间值是什么,并且可以在子查询中使用这些值,则可以将其添加到子查询中:
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
)
您可以按如下方式重写查询:
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
运行该查询时实际会发生什么情况?我得到以下错误:ORA-00904:T1.COLA无效标识符。这是生成的SQL语句的一部分,不幸的是,这些值会根据其他条件而变化,因此我不能依赖它们是相同的。我所能做的就是将我的SQL注入IN子句。谢谢你的SQL Fiddle链接,我不知道这个网站-非常有用。不幸的是,我无法重写整个查询。在这种情况下,我只能在In子句中更改段。