我有一个这样的个人资料表
|--------|-----------|
| People | Favorite |
|--------|-----------|
| A | Movie |
| B | Movie |
| B | Jogging |
|--------|-----------|
问:如何找回最喜欢电影而不是慢跑的人?
在此表中,结果仅为人物A。
尽管我想到了这个
select People from Profile
where
People
in
(select People from Profile
where favorite='Movie')
and
People
not in
(select People from Profile
where favorite='Jogging')
但是,任何建议或答案(不使用join或union子句)似乎都可以更好?
答案 0 :(得分:2)
https://www.db-fiddle.com/f/rboiDpxxbABCpjtduEz7uY/1
SELECT People
FROM `profile`
GROUP BY people
HAVING SUM('Movie' = favorite) > 0
AND SUM('Jogging' = favorite) = 0
答案 1 :(得分:1)
有很多方法。虽然可以使用UNION,但它相当混乱且效率低下。 MySQL没有MINUS子句,该子句可以使查询相当容易理解。
您可以汇总数据:
SELECT people
, MAX(IF(favorite='jogging', 1, 0)) as jogging
, MAX(IF(favorite='movie', 1, 0)) as movie
FROM profile
GROUP BY people
HAVING movie=1 AND jogging=0
或使用外部联接:
SELECT m.people
FROM profile m
LEFT JOIN
( SELECT j.people
FROM joggers j
WHERE j.favorite='jogging' ) joggers
ON m.people=joggers.people
WHERE joggers.people IS NULL
AND m.favorite='movies'
使用NOT IN / NOT EXISTS可以使语法更清晰,但效率仍然很低。
答案 2 :(得分:0)
有几种查询模式将返回满足规范的结果。
我们可以将NOT EXISTS
与相关子查询一起使用:
SELECT p.people
FROM profile p
WHERE p.favorite = 'Movie'
AND NOT EXISTS ( SELECT 1
FROM profile q
WHERE q.favorite = 'Jogging'
AND q.people = p.people /* related to row in out query */
)
ORDER
BY p.people
等效的结果也可以通过 anti-join 模式完成:
SELECT p.people
FROM profile p
LEFT
JOIN profile q
ON q.people = p.people
AND q.favorite = 'Jogging'
WHERE q.people IS NULL
AND p.favorite = 'Movie'
ORDER BY p.people
另一种选择是条件聚合。无法保证唯一性和一些MySQL速记:
SELECT p.people
FROM profile p
GROUP
BY p.people
HAVING 1 = MAX(p.favorite='Movie')
AND 0 = MAX(p.favorite='Jogging')
用于条件聚合的更具可移植性,更符合ANSI标准的语法:
SELECT p.people
FROM profile p
GROUP
BY p.people
HAVING 1 = MAX(CASE p.favorite WHEN 'Movie' THEN 1 ELSE 0 END)
AND 0 = MAX(CASE p.favorite WHEN Jogging' THEN 1 ELSE 0 END)
答案 3 :(得分:0)
当您要在同一列中具有多个条件时,这是一个常见问题。我已经回答了here,并且还有其他方法,例如相交和子查询。
SELECT people, GROUP_CONCAT(favorite) as fav
FROM profile
GROUP BY people
HAVING fav REGEXP 'Movie'
AND NOT fav REGEXP 'Jogging';
答案 4 :(得分:0)
使用group by people
并检查favorite
的最小值和最大值为'Movie'
:
select people from tablename
where favorite in ('Movie', 'Jogging')
group by people
having min(favorite) = 'Movie' and max(favorite) = 'Movie'