#sql #db2
#sql #db2
Вопрос:
У меня есть 2 таблицы:
Значение
---- -------
| id | name |
---- -------
| 1 | Peter |
| 2 | Jane |
| 3 | Joe |
---- -------
Фильтр
---- --------- ------
| id | valueid | type |
---- --------- ------
| 1 | 1 | A |
| 2 | 1 | B |
| 3 | 1 | C |
| 4 | 1 | D |
| 5 | 2 | A |
| 6 | 2 | C |
| 7 | 2 | E |
| 8 | 3 | A |
| 9 | 3 | D |
---- --------- ------
Мне нужно получить значения из таблицы значений, где связанная таблица фильтров не содержит тип ‘B’ или ‘C’
Итак, в этом кратком примере это будет только Joe.
Пожалуйста, обратите внимание, что это DB2 DB, и у меня ограниченные разрешения только для запуска selects.
Ответ №1:
Или также NOT IN (<*fullselect*)
предикат: только то, что мой результат — «Джо», а не «Джейн», и на это будет указывать совокупность данных …
WITH
-- your input, sans reserved words
val(id,nam) AS (
SELECT 1,'Peter' FROM sysibm.sysdummy1
UNION ALL SELECT 2,'Jane' FROM sysibm.sysdummy1
UNION ALL SELECT 3,'Joe' FROM sysibm.sysdummy1
)
,
filtr(id,valueid,typ) AS (
SELECT 1,1,'A' FROM sysibm.sysdummy1
UNION ALL SELECT 2,1,'B' FROM sysibm.sysdummy1
UNION ALL SELECT 3,1,'C' FROM sysibm.sysdummy1
UNION ALL SELECT 4,1,'D' FROM sysibm.sysdummy1
UNION ALL SELECT 5,2,'A' FROM sysibm.sysdummy1
UNION ALL SELECT 6,2,'C' FROM sysibm.sysdummy1
UNION ALL SELECT 7,2,'E' FROM sysibm.sysdummy1
UNION ALL SELECT 8,3,'A' FROM sysibm.sysdummy1
UNION ALL SELECT 9,3,'D' FROM sysibm.sysdummy1
)
-- real query starts here
SELECT
*
FROM val
WHERE id NOT IN (
SELECT valueid FROM filtr WHERE typ IN ('B','C')
)
;
-- out id | nam
-- out ---- -------
-- out 3 | Joe
Или также неудачное соединение слева:
SELECT
val.*
FROM val
LEFT JOIN (
SELECT valueid FROM filtr WHERE typ IN ('B','C')
) filtr
ON filtr.valueid = val.id
WHERE valueid IS NULL
Комментарии:
1. ОП говорит «Джейн», вы говорите «Питер», а я говорю «Джо». ЛОЛ
2. Я ошибочно присоединился к over
USING(id)
вместоval.id
<->filtr.valueid
.. В конце концов, это «Джо» — тем временем исправил мой…3. Хорошо 1. Предостережение: я обычно избегаю
NOT IN
, поскольку это не работает при наличии нулей.4. Да, это была моя ошибка, я на самом деле ищу Джо здесь.
5. … и третий способ, только что добавленный к моему ответу, с использованием неудачного соединения слева. Я не знаю о DB2 так хорошо, как раньше, но, в зависимости от СУБД, один из 3 способов сделать это лучше, чем два других. Стоит изучить …
Ответ №2:
Вы можете использовать EXISTS
, как в:
select *
from value v
where not exists (
select null from filter f
where f.valueid = v.id and f.type in ('B', 'C')
);
Результат:
ID NAME
--- -----
3 Joe
Смотрите Пример выполнения в db<>fiddle.