Mícháte implicitní spojení s explicitními spojeními. To je povoleno, ale musíte si být vědomi toho, jak to udělat správně.
Jde o to, že explicitní spojení (ta, která jsou implementována pomocí JOIN
klíčové slovo) mají přednost před implicitními (spojení 'čárkou', kde je podmínka spojení uvedena v WHERE
doložka).
Zde je přehled vašeho dotazu:
SELECT
…
FROM a, b LEFT JOIN dkcd ON …
WHERE …
Pravděpodobně očekáváte, že se bude chovat takto:
SELECT
…
FROM (a, b) LEFT JOIN dkcd ON …
WHERE …
tedy kombinaci tabulek a
a b
je spojen s tabulkou dkcd
. Ve skutečnosti se to, co se děje,
SELECT
…
FROM a, (b LEFT JOIN dkcd ON …)
WHERE …
to je, jak jste již možná pochopili, dkcd
je spojen specificky proti b
a pouze b
, pak se výsledek spojení zkombinuje s a
a dále filtrováno pomocí WHERE
doložka. V tomto případě jakýkoli odkaz na a
v ON
klauzule je neplatná, a
je v tu chvíli neznámý. Proto se vám zobrazuje chybová zpráva.
Být vámi, pravděpodobně bych se pokusil tento dotaz přepsat a jedním z možných řešení by mohlo být:
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
Zde jsou tabulky a
a b
jsou nejprve spojeny, pak je výsledek spojen s dkcd
. V zásadě se jedná o stejný dotaz jako váš, pouze s použitím jiné syntaxe pro jedno ze spojení, což je velký rozdíl:odkaz a.maxa
v dkcd
Podmínka připojení uživatele je nyní absolutně platná.
Jak správně poznamenal @Aaron Bertrand, pravděpodobně byste měli kvalifikovat maxa
se specifickým aliasem, pravděpodobně a
, v ORDER BY
doložka.