Как объединить два запроса, которые фильтруют два списка объектов A & B, соответственно, связаны ли они с объектом C?

У меня три таблицы: Альфа, Браво и Чарли. У Чарли есть отношения "один-к-одному" как с Альфой, так и с Браво, но любая строка в Чарли будет связана только с Альфой или Браво, ни с обоими. То есть таблица Charlie имеет внешние ключи, связывающие первичный ключ таблицы Alpha и первичный ключ таблицы Bravo, но для любой данной строки в Charlie по крайней мере один из этих внешних ключей будет null.

У меня есть список первичных ключей из Alpha и список первичных ключей из Bravo. Я бы хотел отфильтровать оба списка, чтобы удалить любые строки, связанные с рядом в Charlie.

В настоящее время я делаю это в двух запросах:

SELECT A.a_pk
FROM Alpha A
WHERE A.a_pk IN (1, 2, 5, 17, etc) AND NOT EXISTS (SELECT C.c_pk FROM Charlie C WHERE C.a_pk = A.a_pk)
SELECT B.b_pk
FROM Bravo B
WHERE B.b_pk IN (1, 3, 5, 14, etc) AND NOT EXISTS (SELECT C.c_pk FROM Charlie C WHERE C.b_pk = B.b_pk)

Могут ли эти два запроса быть объединены, и если это так стоит?

Помните, что если C.a_pk имеет значение, C.b_pk будет NULL, и наоборот. Alpha & Bravo не являются симметричными таблицами, но другие столбцы не используются в этих запросах, так как мне просто нужно отфильтровать существующий набор объектов Alpha & Bravo, для которых у меня уже есть все данные.

Комбинированный запрос должен работать как в SQL Server 2008, так и в Oracle.

1 ответ

Эти два запроса могут быть объединены (см. Ниже), должны ли они или нет то, что только вы можете определить - зачем вы хотите?

Комбинированный запрос

SELECT A.a_pk, NULL AS b_pk
FROM Alpha A LEFT OUTER JOIN Charlie C ON ( C.a_pk = A.a_pk )
WHERE C.a_pk IS NULL
--AND A.a_pk IN ( 1, 2, 3, 17 )
UNION ALL
SELECT NULL, B.b_pk
FROM Bravo B LEFT OUTER JOIN Charlie C ON ( C.b_pk = B.b_pk )
WHERE C.b_pk IS NULL
--AND B.b_pk IN ( 1, 3, 5, 14 )

Результаты:

| A_PK | B_PK |
|--------|--------|
| 5 | (null) |
| 3 | (null) |
| (null) | 5 |
| (null) | 3 |
| (null) | 1 |

Oracle - SQLFiddle

SQL Server - SQLFiddle

licensed under cc by-sa 3.0 with attribution.