Выберите строки, которые содержат более одного условия одновременно

StackOverflow https://stackoverflow.com/questions/690545

  •  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 — лучший вариант.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top