2010-06-12 9 views
6

ich die folgenden Tabellen habe:SQL-Join mit NULL-Spalten

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 | 
+-------+------------------+------+

Wenn ich möchte alle Zeilen auszuwählen, aus b, wo gibt es ein entsprechendes Angebot/cid-Paar in a, I Verwenden Sie einfach eine natürliche Verbindung SELECT b.* FROM b NATURAL JOIN a; und alles ist in Ordnung.

Wenn a.bid oder a.cid NULL ist, möchte ich jede Zeile erhalten, wo die andere Spalte übereinstimmt, z. Wenn a.bid NULL ist, möchte ich jede Zeile a.cid=b.cid, wenn beide NULL sind Ich möchte jede Spalte von b.

Meine naive Lösung war:

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)

Gibt es einen besseren Weg, dies zu?

Antwort

2

Nein, das ist es ziemlich.

(I allgemein ISNULL(a.bind) als a.bind IS NULL für ANSI SQL-Kompatibilität FWIW umformulieren würde.)

8

Die ISNULL Funktion ANSI-konform nicht wirklich ist. Ja, Sie müssen in beiden Spalten nach Nullwerten suchen. Eine weitere Möglichkeit, Ihre Abfrage zu schreiben wäre:

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)) 

Noch eine andere Art und Weise, die die Verwendung von Distinct vermeidet:

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 und b.cid kann nicht Null sein, also ist der extra test unnötig, aber ich mag das zweite beispiel ohne distinct. – tstenner

+0

@ tstenner - Ah. Sie haben verpasst, dass Sie die Spalten in b als Nicht-Nullwert angegeben haben. – Thomas

0

Zu alt, aber hier ist meine 2 Cent, könnte es nützlich sein für jemanden

ISNULL (a.cid, 0) = ISNULL (b.cid) uND ISNULL (a.bid, 0) = ISNULL (b.bid)