2012-11-29 14 views
6

Tôi muốn nhận dữ liệu nếu orgid = 2 hoặc nếu không có hàng nào cả cho số uid. orgidinteger. Điều gần nhất tôi có thể nghĩ đến là làm IS NULL nhưng tôi không nhận được dữ liệu cho số uid không có hàng orgid. Bất kỳ ý tưởng?Truy vấn nơi cột khóa ngoài có thể là NULL

select u.uid,u.fname,u.lname from u 
inner join u_org on u.uid = u_org.uid 
inner join login on u.uid = login.uid 
where u_org.orgid=2 or u_org.orgid is NULL 
and login.access != 4; 

Về cơ bản, OR là nếu u_org.orgid hàng không tồn tại.

+1

Đoán của tôi ... bạn đang thiếu dấu ngoặc đơn? Hãy thử thay vào đó: '(u_org.orgid = 2 HOẶC u_org.orgid IS NULL) VÀ login.access! = 4' – Wolph

+0

Ngoài ra, bạn cũng có thể giải quyết nó như sau:' COALESCE (u_org.orgid, 2) = 2' – Wolph

+0

@ WoLpH - cả hai đều không giải quyết được. Có lẽ 'IS NULL' là điều sai trái? Có NULL không nếu hàng không tồn tại trong cơ sở dữ liệu? – user983223

Trả lời

6

Nếu có "không có hàng nào cho uid" và bạn JOIN giống như bạn làm, bạn nhận được không có hàng là kết quả. Sử dụng LEFT [OUTER] JOIN thay vì:

SELECT u.uid, u.fname, u.lname 
FROM u 
LEFT JOIN u_org o ON u.uid = o.uid 
LEFT JOIN login l ON u.uid = l.uid 
WHERE (o.orgid = 2 OR o.orgid IS NULL) 
AND l.access IS DISTINCT FROM 4; 

Ngoài ra, bạn cần ngoặc tôi thêm vì operator precedence. (AND liên kết trước OR).

Tôi sử dụng IS DISTINCT FROM thay vì != trong điều kiện WHERE cuối cùng bởi vì, một lần nữa, login.access có thể là NULL, không đủ điều kiện.

Tuy nhiên, vì bạn chỉ có vẻ quan tâm đến các cột từ bảng u để bắt đầu với, truy vấn thay thế này sẽ là tao nhã hơn:

SELECT u.uid, u.fname, u.lname 
FROM u 
WHERE (u.uid IS NULL OR EXISTS (
    SELECT 1 
    FROM u_org o 
    WHERE o.uid = u.uid 
    AND o.orgid = 2 
    )) 
AND NOT EXISTS (
    SELECT 1 
    FROM login l 
    WHERE l.uid = u.uid 
    AND l.access = 4 
    ); 

Phương án này có lợi thế bổ sung, rằng bạn luôn có được một hàng từ u, ngay cả khi có nhiều hàng trong u_org hoặc login.

+0

@Erwin_Brandstetter - cảm ơn bạn. – user983223