2013-12-06 3 views
0

У меня есть таблица, как так ...Mysql - Выберите по крайней мере один или выберите Нет

---------------------------------------- 
| id |  name  | group | number | 
---------------------------------------- 
| 1 |   joey |  1 |  2 | 
| 2 |   keidy |  1 |  3 | 
| 3 |   james |  2 |  2 | 
| 4 |  steven |  2 |  5 | 
| 5 |   jason |  3 |  2 | 
| 6 |   shane |  3 |  3 | 
---------------------------------------- 

Я бегу выбрать так:

SELECT * FROM table WHERE number IN (2,3); 

Проблема им пытаются решить заключается в том, что я хочу только получить результаты от групп, имеющих 1 или более строк каждого числа. Например, вышеупомянутый запрос возвращает id 1-2-3-5-6, когда мне хотелось бы, чтобы результаты исключали id 3, так как группа «2» может возвращать только 1 результат для числа «2», а не для BOTH 2 и 3, так как нет строки с номером 3 для группы 2, мне бы хотелось даже не выбрать id 3 вообще.

Любая помощь будет отличной.

+2

Ваш вопрос очень запутан. Можете ли вы отредактировать в списке требований/ограничений, которые вы хотите для запроса, а не в абзаце, который у вас там есть? –

+0

То, что вы хотите, называется реляционным делением. [Эта статья] (https: // www.simple-talk.com/sql/t-sql-programming/divided-we-stand-the-sql-of-relational-division/ «Разделенный мы стоим: SQL Relational Division») был опубликован в разделе о Transact- SQL, но по крайней мере некоторые из методов кодируются в SQL, которые также должны быть скомпилированы в MySQL, и по крайней мере некоторые из них должны быть реализованы в MySQL без каких-либо проблем. –

ответ

-1

Может быть, это, если я вас понимаю

SELECT id FROM table WHERE `group` IN 
    (SELECT `group` FROM table WHERE number IN (2,3) 
    GROUP BY `group` 
    HAVING COUNT(DISTINCT number)=2) 

SQL Fiddle

Это возвращает все идентификаторы, где существуют как числа в group.Remove DISTINCT, если вы хотите, идентификаторы для групп, где только один номер в .

+1

Это вернет только 1 идентификатор на группу, где я считаю, что ему нужны все идентификаторы. Я бы подумал использовать вспомогательный запрос с вашим текущим запросом. –

1

Попробуй так

SELECT * 
    FROM table1 t 
WHERE number IN(2, 3) 
    AND EXISTS 
(
    SELECT * 
    FROM table1 
    WHERE number IN(2, 3) 
    AND `group` = t.`group` 
    GROUP BY `group` 
    HAVING MAX(number = 2) > 0 
    AND MAX(number = 3) > 0 
) 

или

SELECT * 
    FROM table1 t JOIN 
(
    SELECT `group` 
    FROM table1 
    WHERE number IN(2, 3) 
    GROUP BY `group` 
    HAVING MAX(number = 2) > 0 
    AND MAX(number = 3) > 0 
) q 
    ON t.`group` = q.`group`; 

или

SELECT * 
    FROM table1 
WHERE `group` IN 
(
    SELECT `group` 
    FROM table1 
    WHERE number IN(2, 3) 
    GROUP BY `group` 
    HAVING MAX(number = 2) > 0 
    AND MAX(number = 3) > 0 
); 

Пример вывода (для обоих запросов):

 
| ID | NAME | GROUP | NUMBER | 
|----|-------|-------|--------| 
| 1 | joey |  1 |  2 | 
| 2 | keidy |  1 |  3 | 
| 5 | jason |  3 |  2 | 
| 6 | shane |  3 |  3 | 

Вот SQLFiddle демо

+0

Я никогда не слышал о SQLFiddle. Это потрясающе! –

1

На этом, вы можете обратиться с интересный способ с несколькими объединениями для того, что вы ХОЧЕТ квалифицировано, OR, применить prequery, чтобы получить все квалифицированные группы, как другие предложили, но читаемость откусила для меня ..

Во всяком случае, вот подход происходит через таблицу один раз, но с соединениями

select DISTINCT 
     T.id, 
     T.Name, 
     T.Group, 
     T.Number 
    from 
     YourTable T 
     Join YourTable T2 
      on T.Group = T2.Group AND T2.Group = 2 
     Join YourTable T3 
      on T.Group = T3.Group AND T3.Group = 3 
    where 
     T.Number IN (2, 3) 

Итак, на первой записи он указывает своей собственной группой группе T2. И группа T2 - это, в частности, 2 ... Затем снова тестирование группы для экземпляра T3 и группы T3 равно 3.

Если он не может завершить соединение с одним из экземпляров T2 или T3, запись будет выполнена для рассмотрения, а так как индексы отлично работают для соединений, таких как это, убедитесь, что у вас есть один индекс для ваших критериев NUMBER и другой индекс для (GROUP, NUMBER) для этих сравнений и следующий пример запроса ...

Если вы делаете более чем эту простую 2, но большую группу , предварительно подготовленные группы, затем присоединитесь к этому

select 
     YT2.* 
    from 
     (select YT1.group 
      from YourTable YT1 
      where YT1.Number in (2, 3) 
      group by YT1.group 
      having count(DISTINCT YT1.group) = 2) PreQualified 
     JOIN YourTable YT2 
     on PreQualified.group = YT2.group 
     AND YT2.Number in (2,3) 
+0

Этот метод является единственным из ответов, который работает так, как он мне нужен. Спасибо. –

+0

@JoeyCadle, рад, что это сработало для вас ... и FYI, вы должны начать проверять ответы, которые хороши, и ПРОВЕРИТЬ ответы, которые являются РЕШЕНИЕМ. В противном случае люди не узнают, разрешено или нет, и тратят время на то, чтобы предложить решение, когда вы, возможно, никогда не оглянетесь назад. – DRapp

+0

Я поддержал это 6 декабря 22:54, может быть, вам просто нужно перезагрузить страницу? Не знаю. –

Смежные вопросы