SQL - выбор уникальных значений из одного столбца с последующей фильтрацией по другому
Я искал вокруг и видел довольно много вопросов о выборе различных значений, но ни одно из них не кажется достаточно близким к моему запросу, чтобы иметь возможность помочь. Это сценарий
ID Product_ID Product_type
123 56789 A
123 78901 B
456 12345 A
789 45612 B
Мне нужен SQL для поиска в таблице, аналогичной приведенной выше, и возврата строк, в которых Product_type
является B
но только если ID
связанный с ним существует один раз в таблице.
Так что в этом случае он вернул бы только
789 45612 B
SQL, который я пробовал на основе того, что я нашел, был
SELECT DISTINCT(ID)
FROM "TABLE"
WHERE "PRODUCT_TYPE" = 'B'
Так же как
SELECT *
FROM "TABLE"
WHERE "PRODUCT_TYPE" = 'B'
GROUP BY "ID"
HAVING COUNT(ID) = 1
И ни один не работал
3 ответа
Один путь через список идентификаторов, появляющихся однажды:
select * from T where Product_type = 'B' and id in (
select id from T
group by id
having count(id) = 1)
Soltuion 1: Используйте подзапрос для подсчета идентификаторов.
select * from table t1
where Product_type = 'B'
and (select count(*) from table
where id = t1.id) = 1
Ты можешь использовать group by
для этого типа запроса. Тем не менее, вы не можете отфильтровать до 'B'
с до агрегации.
Итак, попробуйте это:
SELECT t.id, MAX(t.product_id) as product_id,
MAX(t.product_type) as product_type
FROM "TABLE" t
GROUP BY "ID"
HAVING COUNT(*) = 1 AND
MAX(PRODUCT_TYPE) = 'B';
Это может выглядеть немного загадочно. Но having
предложение гарантирует, что есть только одна строка, и эта строка имеет 'B'
, Следовательно MAX()
функции возвращают максимум из этой строки - это значение в этой строке.
РЕДАКТИРОВАТЬ:
Многие базы данных также позволят вам воспользоваться оконными функциями для этого:
select t.*
from (select t.*, count(*) over (partition by id) as id_cnt
from table t
) t
where t.product_type = 'B' and id_cnt = 1;