Stai mescolando join impliciti con join espliciti. È consentito, ma devi essere consapevole di come farlo correttamente.
Il fatto è che i join espliciti (quelli che vengono implementati usando il JOIN
parola chiave) hanno la precedenza su quelli impliciti (i join 'virgola', dove la condizione di join è specificata in WHERE
clausola).
Ecco uno schema della tua richiesta:
SELECT
…
FROM a, b LEFT JOIN dkcd ON …
WHERE …
Probabilmente ti aspetti che si comporti in questo modo:
SELECT
…
FROM (a, b) LEFT JOIN dkcd ON …
WHERE …
ovvero la combinazione di tabelle a
e b
è unito alla tabella dkcd
. In effetti, quello che sta succedendo è
SELECT
…
FROM a, (b LEFT JOIN dkcd ON …)
WHERE …
ovvero, come forse avrai già capito, dkcd
è unito specificamente a b
e solo b
, quindi il risultato del join viene combinato con a
e filtrato ulteriormente con WHERE
clausola. In questo caso, qualsiasi riferimento a a
nel ON
la clausola non è valida, a
è sconosciuto a quel punto. Ecco perché ricevi il messaggio di errore.
Se fossi in te, probabilmente proverei a riscrivere questa query e una possibile soluzione potrebbe essere:
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
Qui le tabelle a
e b
vengono prima uniti, quindi il risultato viene unito a dkcd
. Fondamentalmente, questa è la tua stessa query, utilizzando solo una sintassi diversa per uno dei join, il che fa una grande differenza:il riferimento a.maxa
nel dkcd
la condizione di unione di ora è assolutamente valida.
Come ha correttamente notato @Aaron Bertrand, dovresti probabilmente qualificare maxa
con uno specifico alias, probabilmente a
, nel ORDER BY
clausola.