一尘不染

交叉联接行为(SQLServer 2008)

sql

我一直在尝试查找有关我的查询的问题。该查询实际上是由HQL的hibernate生成的,但是生成的SQL并没有达到我的期望。稍微修改SQL会产生正确的结果,但是我不确定为什么修改会有所不同。

原始查询(不返回任何行)

select sched.id, max(txn.dttm), acc.id
from PaymentSchedulePeriod sched 
cross join PaymentSchedulePayment pay
right outer join AccountTransaction txn on pay.accountTransactionFk=txn.id 
right outer join Account acc on txn.accountFk=acc.id 
where sched.accountFk=acc.id 
group by sched.id, acc.id

修改的查询-用逗号替换交叉联接(隐式交叉联接)

返回一行

select sched.id, max(txn.dttm), acc.id
from PaymentSchedulePeriod sched 
,PaymentSchedulePayment pay
right outer join AccountTransaction txn on pay.accountTransactionFk=txn.id 
right outer join Account acc on txn.accountFk=acc.id 
where sched.accountFk=acc.id 
group by sched.id, acc.id

我的理解可能是错误的,因为写作from Table1 a, Table2 b与Writing相同from Table 1 a cross join Table2 b。所以我不明白为什么查询返回不同的结果。

与导致此问题的第一个查询中的交叉联接和外部联接之间的交互有关吗?我看过查询计划,第二个查询计划看起来很合理。第一个完全没有外部联接,这很奇怪。

这是在SQLServer 2008上。


阅读 147

收藏
2021-05-23

共1个答案

一尘不染

JOIN的优先级比COMMA高,因此您的第二条语句被解释为(请注意我添加的括号):

select sched.id, max(txn.dttm), acc.id
from PaymentSchedulePeriod sched 
,(PaymentSchedulePayment pay
right outer join AccountTransaction txn on pay.accountTransactionFk=txn.id 
right outer join Account acc on txn.accountFk=acc.id)
where sched.accountFk=acc.id 
group by sched.id, acc.id

另请参阅:每个SQL-99的JOIN优先规则

2021-05-23