Php 如何使用union语句选择mysql数据,其中数据与每个select语句匹配,即将AND运算符与union组合?

Php 如何使用union语句选择mysql数据,其中数据与每个select语句匹配,即将AND运算符与union组合?,php,mysql,select,union,advanced-search,Php,Mysql,Select,Union,Advanced Search,假设我有一个只有两列的表:name和mood。一行包含一个人的名字和他们的情绪,如果他们有多个情绪,那么多行存储在数据库中 例如,数据库中有约翰,他快乐、兴奋、自豪 这表示为 John Happy John Excited John Proud 我想做的是根据满足的几种情绪选择名称。与工会类似: SELECT name WHERE mood=Happy UNION SELECT name WHERE mood=Excited UNION SELECT name WHERE mood=Proud

假设我有一个只有两列的表:name和mood。一行包含一个人的名字和他们的情绪,如果他们有多个情绪,那么多行存储在数据库中

例如,数据库中有约翰,他快乐、兴奋、自豪

这表示为

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
UNIONALL将生成John的一个结果,但它也将选择只匹配其中一个查询的任何名称

我可以想出一些算法,这些算法会占用每个单独的mysql_结果资源(我使用的是PHP),并查找匹配的结果,但我想知道的是mysql是否已经促进了这一点


我意识到以上是一个相当模糊的概括,不用说我的实际程序要复杂得多,我已经对这个问题简化了一些,请不要犹豫提问。

如果我正确理解了你的问题,我认为在这种情况下,实际上不需要
联合
,只需要
WHERE
语句中的多个条件

试试这个:

SELECT name, mood FROM myTable WHERE mood in ('Happy','Excited','Proud')
这将产生以下结果:

John, Happy
John, Excited
John, Proud
John
如果您不在乎获得多个mood结果,请尝试以下方法:

SELECT DISTINCT name FROM myTable WHERE mood in ('Happy','Excited','Proud')
这只会给出:

这将产生以下结果:

John, Happy
John, Excited
John, Proud
John
已更新 如果要匹配所有条件,可能必须使用Subselect:

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')

将UNION替换为INTERSECT。

如果没有重复项,可以使用子查询执行此操作:

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:感谢都铎·康斯坦丁提醒我拥有,第一个问题可以是:

SELECT `name` FROM `moods`
WHERE `mood` IN ('Excited', 'Happy', 'Proud')
GROUP BY `name`
HAVING COUNT(*)>3
尝试:

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

您的查询已经正确。您可以使用
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'

MySQL中没有
INTERSECT
,这是可行的(在SQL中使用
INTERSECT
),但使用3个选择来实现使用一个选择可以实现的功能似乎效率很低?很好,我忘记了,但是为什么要使用额外的连接?此外,MySQL手册还规定“例如,HAVING子句必须位于任何GROUPBY子句之后和任何ORDERBY子句之前。”Paul,感谢您的回复,非常感谢。使用SELECT DISTINCT似乎不会带来任何结果,而您的第一个解决方案确实会带来所有结果。这难道不会返回至少一个情绪匹配(不是全部三个)的所有名称吗?刚刚重试,实际使用DISTINCT会带来结果,但它们不匹配每个条件,即返回其他快乐的人。AND运算符可以应用于您的解决方案吗?非常感谢您的回答,非常感谢。问题是,这会返回只满足其中一个select语句的人的姓名,而不是所有人的姓名。谢谢,我使用了第一个语句,它工作得非常完美,我每天晚上都有一个CRON任务检查重复的语句,所以不用担心。至于更新,它不会返回任何结果,有什么区别呢?非常感谢。have的逻辑基本相同,但不知道是否有任何性能差异。