2011-02-22 23 views
6

Tôi có truy vấn sử dụng mệnh đề IN. Dưới đây là một phiên bản đơn giản:Cột không tồn tại trong mệnh đề IN, nhưng SQL chạy

SELECT * 
    FROM table A 
    JOIN table B 
    ON A.ID = B.ID 
WHERE B.AnotherColumn IN (SELECT Column FROM tableC WHERE ID = 1) 

tableC không có một cột Column, nhưng truy vấn thực hiện tốt mà không có thông báo lỗi. Bất cứ ai có thể giải thích lý do tại sao?

+0

Điều này sẽ cho bạn một lỗi * Cú pháp không chính xác gần từ khóa 'TỪ'. * –

+1

@astander: Tôi đồng ý, nó sẽ đưa ra một lỗi, nhưng nó không phải là –

+0

Xin lỗi, ý tôi là nếu tên cột thực tế là ' Cột'. –

Trả lời

13

Điều này sẽ hoạt động nếu một bảng trong truy vấn bên ngoài có cột của tên đó. Điều này là do các tên cột từ truy vấn bên ngoài có sẵn cho truy vấn con, và bạn có thể có ý định có ý nghĩa để chọn một cột truy vấn bên ngoài trong danh sách truy vấn con của bạn.

Ví dụ:

CREATE TABLE #test_main (colA integer) 
CREATE TABLE #test_sub (colB integer) 

-- Works, because colA is available to the sub-query from the outer query. However, 
-- it's probably not what you intended to do: 
SELECT * FROM #test_main WHERE colA IN (SELECT colA FROM #test_sub) 

-- Doesn't work, because colC is nowhere in either query 
SELECT * FROM #test_main WHERE colA IN (SELECT colC FROM #test_sub) 

Như Damien quan sát, cách an toàn nhất để bảo vệ mình khỏi này không-quá-rõ ràng "Gotcha" là để có được vào các thói quen của đủ điều kiện tên cột của bạn trong subquery:

-- Doesn't work, because colA is not in table #test_sub, so at least you get 
-- notified that what you were trying to do doesn't make sense. 
SELECT * FROM #test_main WHERE colA IN (SELECT #test_sub.colA FROM #test_sub) 
+1

Bạn phải yêu thích các Truy vấn tương quan. Hữu ích trong nhiều lĩnh vực và gây đau buồn cho những người không biết: http://en.wikipedia.org/wiki/Correlated_subquery –

+1

@Stephen Heck, tôi đã biết về điều này trong hơn một thập kỷ, và nó vẫn là chuyến đi tôi lên tất cả bây giờ và một lần nữa. Tôi nghĩ rằng tôi có lẽ là người đầu tiên trả lời bởi vì tôi đã làm nó một lần nữa tuần trước ... Ít nhất với kinh nghiệm lâu dài nó thường là một "D'oh!" Nhanh chóng! tiếp theo là một sửa chữa, thay vì hai giờ khó hiểu về lý do tại sao tôi không nhận được bất kỳ kết quả nào! –

+0

@ Mc Gibson: Một điều chưa được giải quyết, chính xác thì truy vấn 'OUTER' là gì? –

3

Nếu bạn muốn tránh tình huống này trong tương lai (mà Matt Gibson đã giải thích), bạn nên sử dụng bí danh để chỉ định cột. Ví dụ:

SELECT * 
    FROM table A 
    JOIN table B 
    ON A.ID = B.ID 
WHERE B.AnotherColumn IN (SELECT C.Column FROM tableC C WHERE C.ID = 1) 

Điều này sẽ cho bạn một thông báo lỗi tốt (lưu ý rằng nếu không có cột ID trong bảngC, bạn cũng có thêm vấn đề)

+0

+1 Yup, đó là một điểm tốt, và tôi đã thêm nó vào câu trả lời của tôi. –

Các vấn đề liên quan