Соединение SQL с ПУСТЫМИ столбцами

У меня есть следующие таблицы:

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

Когда я хочу выбрать все строки из b, где существует соответствующий bid/cid-pair в a, я просто использую естественное соединение SELECT b.* FROM b NATURAL JOIN a; и все прекрасно.

Когда a.bid или a.cid являются ПУСТЫМИ, я хочу получить каждую строку, где другой столбец соответствует, например, если a.bid является ПУСТЫМ, я хочу каждую строку где a.cid=b.cid, если оба являются ПУСТЫМИ, я хочу каждый столбец от b.

Мое наивное решение было этим:

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 )

Там какой-либо лучший путь к к этому?

8
задан tstenner 12 June 2010 в 11:24
поделиться

2 ответа

Нет, это все.

(Я бы обычно перефразировал ISNULL (a.bind) как a.bind IS NULL для соответствия FWIW ANSI SQL.)

3
ответ дан 5 December 2019 в 12:55
поделиться

Функция ISNULL на самом деле не соответствует стандарту ANSI. Да, вам нужно проверять нули в обоих столбцах. Другой способ написать запрос был бы следующим:

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

Еще один способ, который позволяет избежать использования 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 ) )
                )
9
ответ дан 5 December 2019 в 12:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: