Вы смешиваете неявные объединения с явными объединениями. Это разрешено, но вы должны знать, как это сделать правильно.
Дело в том, что явные объединения (те, которые реализованы с использованием ключевого слова JOIN
) имеют приоритет над неявными (соединения "запятые", где условие соединения указано в предложении WHERE
).
Вот схема вашего запроса:
SELECT
…
FROM a, b LEFT JOIN dkcd ON …
WHERE …
Вы, вероятно, ожидаете, что он будет вести себя так:
SELECT
…
FROM (a, b) LEFT JOIN dkcd ON …
WHERE …
, то есть комбинация таблиц a
и b
объединяется с таблицей dkcd
. На самом деле, то, что происходит,
SELECT
…
FROM a, (b LEFT JOIN dkcd ON …)
WHERE …
то есть, как вы, возможно, уже поняли, dkcd
объединяется специально против b
и только b
, затем результат объединения объединяется с a
и фильтруется далее с помощью предложения WHERE
, В этом случае любая ссылка на a
в предложении ON
является недействительной, a
неизвестна в этот момент. Вот почему вы получаете сообщение об ошибке.
На вашем месте я бы, вероятно, попытался бы переписать этот запрос, и одним из возможных решений может быть:
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
Здесь сначала объединяются таблицы a
и b
, затем результат соединяется с dkcd
. По сути, это тот же запрос, что и у вас, только с использованием другого синтаксиса для одного из соединений, что имеет большое значение: ссылка a.maxa
в условии соединения dkcd
теперь абсолютно действительна.
Как правильно заметил @Aaron Bertrand, вы, вероятно, должны квалифицировать maxa
с определенным псевдонимом, вероятно a
, в предложении ORDER BY
.