Próbuję wyśledzić problem z zapytaniem, które mam. Zapytanie jest faktycznie generowane przez hibernację z HQL, ale wynikowy kod SQL nie spełnia oczekiwań. Modyfikacja SQL lekko daje prawidłowy wynik, ale nie jestem pewien, dlaczego modyfikacja powinna wprowadzić jakąkolwiek różnicę.Zachowanie łączenia krzyżowego (SQLServer 2008)
Original query (nie zwraca wiersze)
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
Zmodyfikowane zapytanie - cross join zastępuje się przecinkiem (niejawny krzyża przyłączyć)
zwraca jeden wiersz
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
mojego zrozumienia, co może być niepoprawny, to pisanie from Table1 a, Table2 b
jest tym samym, co pisanie from Table 1 a cross join Table2 b
. Więc nie rozumiem, dlaczego zapytania zwracają różne wyniki.
Czy jest coś wspólnego z interakcją między łączeniem krzyżowym a zewnętrznymi złączeniami w pierwszym zapytaniu, które to powoduje? Przyjrzałem się planom zapytań, a drugi plan zapytania wygląda rozsądnie. Pierwszy nie ma w ogóle zewnętrznych połączeń, co jest dziwne.
Jest na SQLServer 2008.
Dzięki +1. W moim HQL użyłem COMMA, więc nie jestem pewien, dlaczego hibernacja renderowałaby CROSS JOIN. Zmieniłem klauzule "od", aby tabela "Okres" była ostatnia i działała poprawnie. Nadal powstaje połączenie krzyżowe, ale ponieważ ma ono pierwszeństwo, działa zgodnie z oczekiwaniami. –
@Mike Podkreśla to szorstką krawędź używania RIGHT JOIN zamiast zmiany kolejności, aby użyć LEFT JOIN. Jeśli to zapytanie zostało przepisane, aby umieścić ważne tabele po lewej stronie (i na górze zapytania), cała sprawa UNION vs. przecinek zniknąłaby. – ErikE
@Emtucifor - To prawda, niestety zapytanie to jest generowane przez niektóre Hibernate HQL i ze względu na jego naturę z wykorzystaniem relacji modelu obiektowego, a nie definiowanie dowolnych warunków łączenia, jest trudne do przepisania (a raczej nie wiem jak je przepisać!) –