2010-06-12 40 views
6

Tôi đang gặp các bảng sau:SQL-Tham gia với NULL-cột

Table a 
+-------+------------------+------+-----+ 
| Field | Type    | Null | Key | 
+-------+------------------+------+-----+ 
| bid | int(10) unsigned | YES |  | 
| cid | int(10) unsigned | YES |  | 
+-------+------------------+------+-----+
Table b 
+-------+------------------+------+ 
| Field | Type    | Null | 
+-------+------------------+------+ 
| bid | int(10) unsigned | NO | 
| cid | int(10) unsigned | NO | 
| data | int(10) unsigned | NO | 
+-------+------------------+------+

Khi tôi muốn chọn tất cả các hàng từ b, nơi có một nỗ lực/cid cặp tương ứng trong một, tôi chỉ cần sử dụng tham gia tự nhiên SELECT b.* FROM b NATURAL JOIN a; và mọi thứ đều ổn.

Khi a.bid hoặc a.cid là NULL, tôi muốn nhận được mọi hàng có cột khác phù hợp, ví dụ: nếu a.bid là NULL, tôi muốn mỗi hàng nơi a.cid=b.cid, nếu cả hai là NULL, tôi muốn mỗi cột từ b.

giải pháp ngây thơ của tôi là đây:

SELECT DISTINCT b.* FROM b JOIN a ON (ISNULL(a.bid) OR a.bid=b.bid) AND (ISNULL(a.cid) OR a.cid=b.cid)

Có cách nào tốt hơn để cho điều này?

Trả lời

2

Không, đó là khá nhiều.

(tôi muốn nói chung rephrase ISNULL(a.bind) như a.bind IS NULL cho việc tuân thủ ANSI SQL FWIW.)

8

Chức năng ISNULL không phải là thực sự ANSI tuân thủ. Có, bạn cần phải kiểm tra null trong cả hai cột. Một cách khác để viết truy vấn của bạn sẽ là:

Select Distinct b.* 
From b 
    Join a 
     On (a.bid = b.bid Or (a.bid Is Null And b.bid Is Null)) 
      And (a.cid = b.cid Or (a.cid Is Null And b.cid Is Null)) 

Tuy nhiên, một cách khác mà tránh được việc sử dụng riêng biệt:

Select b.* 
From b 
Where Exists (
       Select 1 
       From a 
       Where (a.bid = b.bid Or (a.bid Is Null And b.bid Is Null)) 
        And (a.cid = b.cid Or (a.cid Is Null And b.cid Is Null)) 
       ) 
+0

b.bid và b.cid không thể là Null, do đó, kiểm tra thêm là không cần thiết, nhưng tôi thích ví dụ thứ hai mà không có sự khác biệt. – tstenner

+0

@tstenner - Ah. Đã bỏ lỡ rằng bạn đã nêu các cột trong b là không có giá trị. – Thomas

0

Quá cũ, nhưng đây là 2 cent của tôi, nó có thể có ích cho một ai đó

ISNULL (a.cid, 0) = ISNULL (b.cid) VÀ ISNULL (a.bid, 0) = ISNULL (b.bid)

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