Bạn đang trộn các phép nối ngầm với các phép nối rõ ràng. Điều đó được cho phép, nhưng bạn cần biết cách thực hiện điều đó đúng cách.
Vấn đề là, các phép nối rõ ràng (các phép nối được triển khai bằng cách sử dụng JOIN
từ khóa) được ưu tiên hơn những từ khóa ngầm định (kết hợp 'dấu phẩy', trong đó điều kiện kết hợp được chỉ định trong WHERE
mệnh đề).
Đây là phác thảo về truy vấn của bạn:
SELECT
…
FROM a, b LEFT JOIN dkcd ON …
WHERE …
Bạn có thể đang mong đợi nó hoạt động như thế này:
SELECT
…
FROM (a, b) LEFT JOIN dkcd ON …
WHERE …
nghĩa là, sự kết hợp của các bảng a
và b
được kết hợp với bảng dkcd
. Trên thực tế, những gì đang xảy ra là
SELECT
…
FROM a, (b LEFT JOIN dkcd ON …)
WHERE …
nghĩa là, như bạn có thể đã hiểu, dkcd
được kết hợp cụ thể với b
và chỉ b
, sau đó kết quả của phép nối được kết hợp với a
và được lọc thêm bằng WHERE
mệnh đề. Trong trường hợp này, mọi tham chiếu đến a
trong ON
mệnh đề không hợp lệ, a
không rõ tại thời điểm đó. Đó là lý do tại sao bạn nhận được thông báo lỗi.
Nếu tôi là bạn, tôi có thể sẽ cố gắng viết lại truy vấn này và một giải pháp khả thi có thể là:
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
Đây là các bảng a
và b
được nối đầu tiên, sau đó kết quả được nối với dkcd
. Về cơ bản, đây là truy vấn giống với truy vấn của bạn, chỉ sử dụng cú pháp khác cho một trong các phép nối, điều này tạo ra sự khác biệt lớn:tham chiếu a.maxa
trong dkcd
Điều kiện tham gia của bây giờ hoàn toàn hợp lệ.
Như @Aaron Bertrand đã lưu ý chính xác, bạn có thể đủ điều kiện maxa
với một bí danh cụ thể, có thể là a
, trong ORDER BY
mệnh đề.