2011-08-24 29 views
6

Tôi gặp vấn đề với chế độ xem tôi muốn tạo. Tôi có hai bảng được nối trong một kết nối bên ngoài bên trái, giả sử tableAtableB, trong đó tableB được nối với nhau bên ngoài.mệnh đề SQL cho phép nối ngoài bên trái

Tôi muốn chỉ chọn những hàng từ bảng B trong đó trạng thái bằng 4, vì vậy tôi thêm WHERE state = 4 vào truy vấn của mình. Bây giờ tập kết quả được cắt khá một chút vì tất cả các hàng không có hàng phù hợp trong tableB đều bị xóa khỏi kết quả (vì trạng thái không phải là 4 cho các hàng đó). Tôi cũng đã thử WHERE state = 4 OR state IS NULL, không hoạt động (hoặc từ state về mặt kỹ thuật không phải là NULL khi không có trạng thái).

Vì vậy, những gì tôi cần là tuyên bố WHERE chỉ được đánh giá khi có thực sự là một hàng, có tồn tại một thứ như vậy không?

Nếu tôi không thấy hai tùy chọn: join (SELECT * FROM tableB WHERE state = 4) thay vì bảng B hoặc tạo chế độ xem có cùng tuyên bố WHERE và tham gia thay vào đó. Hiệu suất tùy chọn tốt nhất là gì?

Đây là SQL Server 2008 R2 bằng cách này.

+1

sẽ rất thú vị để cố gắng tìm ra lý do tại sao 'Ở ĐÂU state = 4 OR bang lÀ NULL' không hoạt động, vì nó sẽ ngăn chặn trái join được chuyển đổi thành một bên trong tham gia. –

+0

@Damien_The_Unbeliever - Nó sẽ cung cấp cho bạn tất cả các hàng từ TableA chứ không phải trong TableB nhưng không phải là các hàng mà TableA có một kết quả phù hợp trong TableB, trong đó trạng thái <> 4. http://data.stackexchange.com/stackoverflow/qt/110316/ –

+0

@ Damien_The_Unbeliever: có 3 trạng thái: phù hợp với trạng thái = 4, phù hợp với trạng thái <> 4, không khớp – gbn

Trả lời

6

Bạn đặt các điều kiện trong mệnh đề on. Ví dụ:

select a.this, b.that 
from TableA a 
left join TableB b on b.id = a.id and b.State = 4 
+0

Ah, tôi không biết điều đó! Cảm ơn! – Jasper

4

Bạn có thể thêm state = 4 vào điều kiện tham gia.

select * 
from T1 
    left outer join T2 
    on T1.T1ID = T2.T1ID and 
     T2.state = 4 
1

Thậm chí dễ hơn truy vấn con đang mở rộng mệnh đề on, như;

select * 
from TableA a 
left join 
     TableB b 
on  a.b_id = b.id 
     and b.state = 4 

Tất cả các hàng từ TableA sẽ xuất hiện, và chỉ những từ TableB với nhà nước 4.

SQL Server có thể sẽ thực hiện xem, mở rộng on, và subquery trong chính xác cùng một cách. Vì vậy, hiệu suất khôn ngoan, cần có sự khác biệt nhỏ.

0

phương pháp thay thế: (1) bên tham gia vào bảng B, nơi nhà nước tương đương với 4, (2) antijoin bảng B để tìm hàng mà không tồn tại, (3) công đoàn các kết quả:

SELECT A1.ID, A1.colA, B1.ColB 
    FROM tableA AS A1 
     INNER JOIN tableB AS B1 
      ON A1.ID = B1.ID 
      AND B1.state = 4 
UNION 
SELECT A1.ID, A1.colA, '{{MISSING}}' AS ColB 
    FROM tableA AS A1 
WHERE NOT EXISTS (
        SELECT * 
        FROM tableB AS B1 
        WHERE A1.ID = B1.ID 
       ); 

Hoặc:

SELECT A1.ID, A1.colA, B1.ColB 
    FROM tableA AS A1 
     JOIN tableB AS B1 
      ON A1.ID = B1.ID 
      AND B1.state = 4 
UNION 
SELECT ID, colA, '{{NA}}' AS ColB 
    FROM tableA 
WHERE ID IN (
       SELECT ID 
       FROM tableA 
       EXCEPT 
       SELECT ID 
       FROM tableB 
      ); 
Các vấn đề liên quan