2010-06-12 5 views
6

Je vais avoir les tableaux suivants:SQL-Join avec des colonnes NULL-

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

Quand je veux sélectionner toutes les lignes de b où il y a une offre/cid paire dans un correspondant, je Il suffit d'utiliser une jointure naturelle SELECT b.* FROM b NATURAL JOIN a; et tout va bien.

Lorsque a.bid ou a.cid est NULL, je veux obtenir chaque ligne où l'autre colonne correspond, par ex. si a.bid est NULL, je veux chaque ligne où a.cid=b.cid, si les deux sont NULL, je veux que chaque colonne de b.

Ma solution naïve était ceci:

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)

Y at-il une meilleure façon de ce?

Répondre

2

Non, c'est à peu près tout.

(généralement je reformule ISNULL(a.bind) comme a.bind IS NULL pour ANSI SQL conformité FWIW.)

8

La fonction ISNULL n'est pas réellement conforme aux normes ANSI. Oui, vous devez vérifier les valeurs NULL dans les deux colonnes. Une autre façon d'écrire votre requête serait:

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

Encore une autre façon qui évite l'utilisation de Distinct:

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 et b.cid ne peut pas être nul, donc le test supplémentaire est inutile, mais j'aime le second exemple sans distincte. – tstenner

+0

@tstenner - Ah. Vous avez manqué que vous ayez déclaré que les colonnes de b n'étaient pas nulles. – Thomas

0

Trop vieux, mais voici mes 2 cents, il pourrait être utile pour quelqu'un

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

Questions connexes