2010-06-12 15 views
6

estoy teniendo las siguientes tablas:SQL-Unir con NULL columnas

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

Cuando quiero para seleccionar todas las filas de B donde hay una oferta/cid-par correspondiente en una, me simplemente use una combinación natural SELECT b.* FROM b NATURAL JOIN a; y todo estará bien.

Cuando a.bid o a.cid es NULL, quiero obtener cada fila donde coincida la otra columna, p. si a.bid es NULL, quiero que cada fila sea a.cid=b.cid, si ambas son NULL. Quiero que cada columna sea de b.

Mi solución ingenua era la siguiente:

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)

¿Hay alguna manera mejor que esto?

Respuesta

2

No, eso es todo.

(Me lo general reformular ISNULL(a.bind) como a.bind IS NULL para el cumplimiento de la norma ANSI SQL Fwiw.)

8

La función ISNULL en realidad no es compatible con ANSI. Sí, necesita verificar nulos en ambas columnas. Otra manera de escribir la consulta sería:

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

Sin embargo, otra forma que evite el uso de distintas:

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 y b.cid no puede ser nulo, entonces la prueba adicional es innecesaria, pero me gusta el segundo ejemplo sin distinción. – tstenner

+0

@tstenner - Ah. Perdió que usted declaró las columnas en b como no nulos. – Thomas

0

demasiado viejo, pero aquí es mi 2 centavos, podría ser útil para alguien

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