7

私は自分が持っているクエリの問題を突き止めようとしています。クエリは実際にはHQLからの休止状態によって生成されますが、結果の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

変更されたクエリ-クロス結合がコンマに置き換えられました(暗黙のクロス結合)

1行を返します

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と同じfrom Table 1 a cross join Table2 bです。そのため、クエリが異なる結果を返す理由がわかりません。

これを引き起こす最初のクエリでのクロス結合と外部結合の間の相互作用と関係がありますか?クエリプランを確認しましたが、2番目のクエリプランは妥当なようです。最初のものには外部結合がまったくありませんが、これは奇妙なことです。

これはSQLServer2008にあります。

4

2 に答える 2

9

JOINはCOMMAよりも優先順位が高いため、2番目のステートメントは次のように解釈されます(追加した括弧に注意してください)。

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優先順位ルール

于 2011-01-24T17:37:31.593 に答える
0

実際のデータとクエリプランを見ずに、オプティマイザーがクエリプランを作成する方法に関係していると思います(わかりました)。

最初の例では、「最初のテーブルを取得し、2番目のテーブルとクロス結合し、次に3番目のテーブルで右結合し、次に4番目のテーブルで右結合する」ように明示的に指示されています。

第二に、そのクロスジョインは(少なくとも私の考え方では)暗黙的です。これは、すべての結合がWHERE句で実行されていた時代からの「古い」SQL構文です。これもまた、私の考え方では、データベースエンジンが独自の順序で自由に実行できることを意味します。プロセステーブル。つまり、SQLはテーブルを結合するための特定の順序を与えていません。(内部結合と相互結合では違いはありませんが、外部結合では大きな違いがあります。)

...技術的に正確であるため、@ Joeの回答(賛成)が好きです。とにかく詳細のために自分で投げています。

于 2011-01-24T17:41:48.523 に答える