我知道,这个问题被问了很多次,但我就是不明白。
重要列:
- 姓名
- 日期
- 类别
已保存的数据:
每个名称都会存储多次,即使是相同的类别,例如:
name | category | date
-----|----------|-------
jeff | exCat | 2015-07-02
paul | red | 2015-07-04
jeff | red | 2015-07-03
paul | blue | ...
kevin| green | ...
jeff | green | ...
mike | red
在这种情况下>>排除jeff并输出所有其他人。
目标:
选择此时间跨度内任何位置不具有特定类别(此处称为“exCat”)的两个日期之间的所有名称。
听起来很简单不是吗?嗯,反正也拿不到。第一部分很简单:
SELECT name FROM myTable WHERE date >= @start AND date <= @end
(也可以使用BETWEEN
)。
然后我需要类似 WHERE category NOT LIKE "exCat"
的东西.
这行不通。这个查询将输出除“exCat”之外至少有一个其他类别的每个人。但我需要的人在这个特定的时间范围内一次也不包含“exCat”。
一种可能的情况:
SELECT
name AS Name
FROM myTable
WHERE date >= @start AND
date <= @end AND
Name NOT IN (SELECT
name
FROM myTable
WHERE date >= @start AND
date <= @end AND
category LIKE "exCat")
GROUP BY name
所以这就像 SELECT name WHERE name NOT IN (SELECT name WHO GOT AT LEAST 1 "exCat")
像这样,我只会排除那些至少有一个“exCat”的人,例如我会得到一个结果,人们在任何地方都没有“exCat”。
问题在于:每个子查询大约需要 0.05 秒,两者加起来大约需要 15 分钟。太多了。
最佳答案
您可以使用条件聚合:
SELECT name
FROM mytable
GROUP BY name
HAVING COUNT(CASE WHEN category = 'exCat' THEN 1 END) = 0
这是一种在不使用子查询的情况下仅排除获得至少一个 exCat
的人的方法。
关于Mysql - 按返回零进行计数和分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31748334/