Je combineert impliciete joins met expliciete joins. Dat mag, maar je moet wel weten hoe je dat op de juiste manier doet.
Het punt is, expliciete joins (degenen die worden geïmplementeerd met behulp van de JOIN
trefwoord) hebben voorrang op impliciete (de 'komma'-joins, waarbij de join-voorwaarde is opgegeven in de WHERE
clausule).
Hier is een overzicht van uw vraag:
SELECT
…
FROM a, b LEFT JOIN dkcd ON …
WHERE …
Je verwacht waarschijnlijk dat het zich als volgt gedraagt:
SELECT
…
FROM (a, b) LEFT JOIN dkcd ON …
WHERE …
dat wil zeggen, de combinatie van tabellen a
en b
wordt samengevoegd met de tabel dkcd
. Wat er in feite gebeurt, is
SELECT
…
FROM a, (b LEFT JOIN dkcd ON …)
WHERE …
dat wil zeggen, zoals je misschien al hebt begrepen, dkcd
is specifiek aangesloten tegen b
en alleen b
, dan wordt het resultaat van de join gecombineerd met a
en verder gefilterd met de WHERE
clausule. In dit geval is elke verwijzing naar a
in de ON
clausule is ongeldig, a
is op dat moment niet bekend. Daarom krijg je de foutmelding.
Als ik jou was, zou ik waarschijnlijk proberen deze vraag te herschrijven, en een mogelijke oplossing zou kunnen zijn:
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
Hier de tabellen a
en b
worden eerst samengevoegd, dan wordt het resultaat toegevoegd aan dkcd
. In principe is dit dezelfde query als de jouwe, alleen met een andere syntaxis voor een van de joins, wat een groot verschil maakt:de referentie a.maxa
in de dkcd
's deelnamevoorwaarde is nu absoluut geldig.
Zoals @Aaron Bertrand terecht heeft opgemerkt, zou je waarschijnlijk in aanmerking moeten komen voor maxa
met een specifieke alias, waarschijnlijk a
, in de ORDER BY
clausule.