Выберите строки, которые содержат более одного условия одновременно
-
22-08-2019 - |
Вопрос
У меня есть структура таблицы такая:
ID cond
1 5
1 2
1 6
8 2
9 1
9 5
Когда я хочу выбрать строки, которые содержат одно или несколько условий, которые я использую, или (... когда cond = 2 или cond = 6 группа по Id ...)
Но как выбрать строки, содержащие более одного условия, одновременно сгруппированные по идентификатору?Например.когда я хочу найти строки, содержащие cond 2 и 6, он возвращает только идентификатор 1
Спасибо
Решение
Есть несколько способов сделать это.
С использованием COUNT
(самый быстрый):
SELECT id FROM tbl WHERE tbl.cond IN ( 2, 6 ) HAVING COUNT(DISTINCT cond) = 2 GROUP BY id
С использованием EXISTS
(с использованием вложенных циклов, медленнее на очень больших таблицах, но менее загадочно и более расширяемо, чем COUNT
вариант):
SELECT DISTINCT id FROM tbl AS tbl1 WHERE EXISTS (SELECT * FROM tbl AS tbl2 WHERE tbl1.id = tbl2.id AND tbl2.cond = 2) AND EXISTS (SELECT * FROM tbl AS tbl2 WHERE tbl1.id = tbl2.id AND tbl2.cond = 6)
С использованием GROUP_CONCAT
(специфичный для MySql вариант темы COUNT, но если вам когда-нибудь понадобятся точные совпадения, напримерcond=2 и cond=6, никаких других условий, затем приведенное ниже, измененное на следующее: SELECT id, GROUP_CONCAT(DISTINCT cond ORDER BY cond) AS conds ... WHERE conds='2,6'
будет лучше всех)
SELECT id, ','||GROUP_CONCAT(DISTINCT cond)||',' AS conds FROM tbl WHERE INSTR(conds, ',2,') > 0 AND INSTR(conds, ',6,') > 0 GROUP BY id
Другие советы
Для этого вы можете использовать соединение:
SELECT ID
FROM tbl t1
INNER JOIN
tbl t2
ON t1.ID = t2.ID
WHERE t1.cond = 2
AND t2.cond = 6
Или это, если пары идентификатор/условие уникальны:
SELECT ID
FROM tbl
WHERE cond IN (2, 6)
GROUP BY ID
HAVING COUNT(cond) = 2
Для этого вы можете использовать подзапросы и группы.Предполагая, что вы знаете количество значений, которые вам нужно найти, вы можете сделать это:
select
t.ID
from
(
select distinct
ID, cond
from
tbl
where
tbl.cond in (2, 6)
) as t
group by
t.ID
having
count(t.cond) = 2
В общем случае вам просто нужно будет обновить список условий, которые должны существовать (т.е.«(2, 6)»), чтобы включить новые значения, а затем обновить предложение наличия (т.е.«имеющий count(t.cond) = 2»), чтобы равняться общему количеству значений.
SELECT DISTINCT(ID) WHERE (cond = 2) OR (cond = 6)
Вот еще один синтаксис, который немного более прозрачен (хотя и не так эффективен) в отношении того, что он делает.
SELECT DISTINCT ID
FROM MyTable T
WHERE
EXISTS(SELECT ID FROM MyTable T1 WHERE Cond=2 AND T1.ID=T.ID) AND
EXISTS(SELECT ID From MyTable T2 WHERE Cond=6 AND T2.ID=T.ID)
Это может быть немного более гибко, если для каждого идентификатора нет дубликатов.
SELECT id
FROM tbl
GROUP BY id
HAVING SUM(CASE cond
WHEN 2 THEN 1
WHEN 6 THEN 1
ELSE 0 END) > 1
Задумывались ли вы об использовании предложения UNION?
Выберите идентификатор Mytable, где Cond = 2 Union Select Id из Mytable, где cond = 6
Также было бы полезно, если бы вы могли указать точный результат, который вы ищете.Но, насколько я понял, UNION — лучший вариант.