SQL-子查询和外部表之间的关系
问题 我需要更好地理解关于何时可以在子查询中引用外部表以及何时(以及为什么)这是一个不合适的请求的规则。我在试图重构的Oracle SQL查询中发现了一个重复,但当我试图将引用表转换为分组子查询时遇到了问题 以下语句适用:SQL-子查询和外部表之间的关系,sql,subquery,correlated-subquery,derived-table,inline-view,Sql,Subquery,Correlated Subquery,Derived Table,Inline View,问题 我需要更好地理解关于何时可以在子查询中引用外部表以及何时(以及为什么)这是一个不合适的请求的规则。我在试图重构的Oracle SQL查询中发现了一个重复,但当我试图将引用表转换为分组子查询时遇到了问题 以下语句适用: SELECT t1.* FROM table1 t1, INNER JOIN table2 t2 on t1.id = t2.id and t2.date = (SELECT max(date)
SELECT t1.*
FROM table1 t1,
INNER JOIN table2 t2
on t1.id = t2.id
and t2.date = (SELECT max(date)
FROM table2
WHERE id = t1.id) --This subquery has access to t1
不幸的是,表2有时有重复的记录,所以我需要先聚合t2,然后再将其加入t1。但是,当我尝试将其包装到子查询中以完成此操作时,突然SQL引擎无法再识别外部表
SELECT t1.*
FROM table1 t1,
INNER JOIN (SELECT *
FROM table2 t2
WHERE t1.id = t2.id --This loses access to t1
and t2.date = (SELECT max(date)
FROM table2
WHERE id = t1.id)) sub on t1.id = sub.id
--Subquery loses access to t1
我知道这些是根本不同的查询,我要求编译器把它们放在一起,但我不明白为什么一个可以工作,而另一个不行
我知道我可以复制子查询中的表引用,并有效地将子查询与外部表分离,但这似乎是完成此任务的一种非常糟糕的方式(所有代码和处理的重复)
有用的参考资料
- 我发现了对SQL Server中子句执行顺序的奇妙描述:()。我正在使用Oracle,但我认为这将是全面的标准。对子句求值有一个明确的顺序(从第一个开始),因此我认为任何出现在列表后面的子句都可以访问以前处理过的所有信息。我只能假设我的第二个查询以某种方式改变了顺序,以至于我的子查询被计算得太早了
- 此外,我还发现了一个类似的问题( )但是,尽管投入很好,他们从未真正解释为什么他不能做他正在做的事情,只是给出了解决问题的替代方案。我尝试过他们的替代解决方案,但这给我带来了其他问题。也就是说,带有日期引用的子查询是整个操作的基础,所以我无法摆脱它
- 我想知道我在这里做了什么。。。为什么我的初始子查询可以看到外部表,但在我将整个语句包装到子查询中后却看不到
- 也就是说,如果我试图做的事情无法完成,那么重构第一个查询以消除重复的最佳方法是什么?我是否应该参考表1两次(包括所有需要的重复)?或者有(可能)更好的方法来解决这个问题吗
因此,我由一位同为开发人员的人运行了这个程序,他对为什么我的子查询无法访问t1有一个可能的解释。因为我将这个子查询包装在一个括号中,所以他认为这个子查询是在我的表t1被计算之前被计算的。这肯定可以解释我收到的“ORA-00904:t1”“id:无效标识符”错误。它还表明,与运算的算术顺序一样,向语句中添加paren可以使语句在某些子句计算中具有优先级。如果他们同意/不同意,我仍然希望专家能够参与进来,这是我在这里看到的合乎逻辑的解释。以下问题如何:
SELECT t1.* FROM
(
SELECT *
FROM
(
SELECT t2.id,
RANK() OVER (PARTITION BY t2.id, t2.date ORDER BY t2.date DESC) AS R
FROM table2 t2
)
WHERE R = 1
) sub
INNER JOIN table1 t1
ON t1.id = sub.id
在第二个示例中,您试图将t1引用向下传递两个级别。。你不能这样做,你只能通过一级(这就是为什么第一级有效)。如果你能给出一个更好的例子来说明你想做什么,我们也可以帮助你重写你的查询。所以我根据Martin Smith在上面的评论(谢谢Martin!)得出了这个结论,我想确保我将我的发现分享给任何遇到这个问题的人 技术注意事项 首先,如果我使用合适的术语来描述我的问题,肯定会有所帮助:我上面的第一个语句使用了一个相关子查询: