Mieszasz niejawne sprzężenia z jawnymi sprzężeniami. Jest to dozwolone, ale musisz wiedzieć, jak to zrobić prawidłowo.
Chodzi o to, że jawne złączenia (te, które są zaimplementowane za pomocą JOIN
słowa kluczowego) mają pierwszeństwo przed niejawnymi (połączenia „przecinkowe”, gdzie warunek złączenia jest określony w WHERE
klauzula).
Oto zarys Twojego zapytania:
SELECT
…
FROM a, b LEFT JOIN dkcd ON …
WHERE …
Prawdopodobnie spodziewasz się, że będzie się zachowywał tak:
SELECT
…
FROM (a, b) LEFT JOIN dkcd ON …
WHERE …
czyli kombinacja tabel a
i b
jest połączony z tabelą dkcd
. W rzeczywistości to, co się dzieje, to
SELECT
…
FROM a, (b LEFT JOIN dkcd ON …)
WHERE …
to znaczy, jak być może już zrozumiałeś, dkcd
jest połączony specjalnie z b
i tylko b
, wynik połączenia jest łączony z a
i dalej filtrowane za pomocą WHERE
klauzula. W tym przypadku wszelkie odniesienia do a
w ON
klauzula jest nieprawidłowa, a
jest w tym momencie nieznany. Dlatego pojawia się komunikat o błędzie.
Na Twoim miejscu prawdopodobnie spróbowałbym przepisać to zapytanie, a jednym z możliwych rozwiązań mogłoby być:
SELECT DISTINCT
a.maxa,
b.mahuyen,
a.tenxa,
b.tenhuyen,
ISNULL(dkcd.tong, 0) AS tongdkcd
FROM phuongxa a
INNER JOIN quanhuyen b ON LEFT(a.maxa, 2) = b.mahuyen
LEFT OUTER JOIN (
SELECT
maxa,
COUNT(*) AS tong
FROM khaosat
WHERE CONVERT(datetime, ngaylap, 103) BETWEEN 'Sep 1 2011' AND 'Sep 5 2011'
GROUP BY maxa
) AS dkcd ON dkcd.maxa = a.maxa
WHERE a.maxa <> '99'
ORDER BY a.maxa
Tutaj tabele a
i b
są łączone jako pierwsze, a wynik jest dołączany do dkcd
. Zasadniczo jest to to samo zapytanie co twoje, tylko przy użyciu innej składni dla jednego z łączeń, co robi wielką różnicę:odwołanie a.maxa
w dkcd
Warunek dołączenia jest teraz całkowicie poprawny.
Jak słusznie zauważył @Aaron Bertrand, prawdopodobnie powinieneś zakwalifikować maxa
z określonym aliasem, prawdopodobnie a
, w ORDER BY
klauzula.