Как я могу выбрать данные MySQL с помощью оператора объединения, где данные соответствуют каждому оператору выбора, то есть объединить оператор AND с UNION? - PullRequest
1 голос
/ 21 января 2012

Допустим, у меня есть таблица с двумя столбцами: имя и настроение . Строка содержит имя человека и его настроение, если у них несколько настроений, то в БД хранятся несколько рядов.

Например, в базе данных находится Джон, который счастлив, взволнован и горд.

Это представляется как

John Happy
John Excited
John Proud

Что я хочу сделать, это выбрать имя, основываясь на нескольких встречаемых настроениях. Похоже на СОЮЗ:

SELECT name WHERE mood=Happy
UNION
SELECT name WHERE mood=Excited
UNION
SELECT name WHERE mood=Proud

Однако использование вышеприведенного объединения приведет к:

John
John
John

Объединение всех приведет к единственному результату Джона, но также выберет любые имена, которые соответствуют только одному из запросов.

Я могу придумать несколько алгоритмов, которые бы использовали каждый отдельный ресурс mysql_result (я использую PHP) и искали соответствующие результаты, но я хочу знать, облегчает ли это MySQL.

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

Ответы [ 5 ]

3 голосов
/ 21 января 2012

Если у вас нет дубликатов, вы можете сделать это с помощью подзапроса:

SELECT `name` FROM (
    SELECT `name`, COUNT(*) AS `count` FROM `moods`
    WHERE `mood` IN ('Excited', 'Happy', 'Proud') GROUP BY `name`
) WHERE `count` = 3

В качестве альтернативы, вы можете использовать объединение:

SELECT `m1`.`name` FROM `moods` `m1`
JOIN `moods` `m2` USING (`name`)
JOIN `moods` `m3` USING (`name`)
WHERE `m1`.`mood` = 'Excited' AND `m2`.`mood` = 'Happy' AND `m3`.`mood` = 'Proud'

Не так мило, но может быть быстрееесли вы используете LIMIT.А может и нет.Много зависит от планировщика запросов.

UPD : спасибо Тудору Константину за напоминание о HAVING, первый запрос может быть:

SELECT `name` FROM `moods`
WHERE `mood` IN ('Excited', 'Happy', 'Proud')
GROUP BY `name`
HAVING COUNT(*)>3
1 голос
/ 21 января 2012

Ваш запрос уже правильный. Вы можете ADD дополнительный столбец, используя искомое слово в предложении WHERE.

SELECT name,'Happy' as imood WHERE mood='Happy'
  UNION
SELECT name,'Excited' as imood WHERE mood='Excited'
  UNION
SELECT name,'Proud' as imood WHERE mood='Proud'
1 голос
/ 21 января 2012

Попробуйте с:

SELECT name FROM user_moods um1 
  INNER JOIN user_moods um2 ON um1.name = um2.name
WHERE um1.mood IN ('Happy','Excited','Proud')
GROUP BY um2.mood
HAVING COUNT(um2.mood) = 3 # the number of different moods
1 голос
/ 21 января 2012

Если я правильно понимаю ваш вопрос, я думаю, что в этом случае вам на самом деле не нужен UNION, а просто несколько условий в выражении WHERE.

Попробуйте это:

SELECT name, mood FROM myTable WHERE mood in ('Happy','Excited','Proud')

Это должно дать результат:

John, Happy
John, Excited
John, Proud

Если вам не важно получить несколько результатов по настроению, попробуйте следующее:

SELECT DISTINCT name FROM myTable WHERE mood in ('Happy','Excited','Proud')

Который просто даст:

Это должно дать результат:

John

Обновлено Если вы хотите соответствовать ВСЕМ условиям, вам, вероятно, придется использовать подвыборы:

SELECT DISTINCT name FROM myTable 
WHERE name IN 
    (SELECT name FROM myTable WHERE mood = 'Happy')
AND name IN
    (SELECT name FROM myTable WHERE mood = 'Excited')
AND name IN
    (SELECT name FROM myTable WHERE mood = 'Proud')
0 голосов
/ 21 января 2012

Заменить UNION на INTERSECT.

...