SQL -- WHERE、GROUP BY、HAVING 查询

Posted

技术标签:

【中文标题】SQL -- WHERE、GROUP BY、HAVING 查询【英文标题】:SQL -- WHERE, GROUP BY, HAVING query 【发布时间】:2021-12-31 04:53:56 【问题描述】:

一张表grade 看起来像这样

course year pass
English 2019 Yes
Math 2020 Yes
Math 2020 No
Chemistry 2021 No

它显示学生在每个日历年中所有课程的成绩。一门课程每年可以参加多次。 pass的数据类型是bool。现在我想知道在 2020 年和 2021 年每年至少通过一次的所有课程。

我的查询是

SELECT course 
FROM grade
WHERE year IN (2020, 2021)
GROUP BY course, year
HAVING SUM(pass) > 0;

但它显示课程满足 2020 年或 2021 年。如何仅显示课程满足 2020 年和 2021 年?

【问题讨论】:

你用的是mysql、sql server还是postgresql?您标记了所有这些。 我觉得没关系,也可以看成伪sql。 这确实很重要。这个问题很容易用条件聚合来回答,但是 Postgres 等支持FILTER,SQL Server 不支持。 SQL Server 也不支持bool 列,仅支持bit 【参考方案1】:

这个查询可以工作

SELECT course 
FROM grade
WHERE year IN (2020, 2021)
AND pass = 'yes'
GROUP BY course
HAVING COUNT(DISTINCT year) = 2

【讨论】:

【参考方案2】:

我不确定此查询是否会涵盖所有极端情况,但您可以尝试一下;

SELECT course FROM grade WHERE pass='yes' and (year=2021 or year=2020);

【讨论】:

而不是添加“这应该工作......”作为答案提供了详细的答案,实际上会提供问题的答案。 我会尽快实施。感谢您的建议@Tyler2P。【参考方案3】:

在相当通用的 SQL 中,您可以使用条件聚合

SELECT course 
FROM grade
WHERE year IN (2020, 2021)
AND pass = 'yes'
GROUP BY course
HAVING COUNT(CASE WHEN year = 2020 THEN 1 END) > 0
   AND COUNT(CASE WHEN year = 2021 THEN 1 END) > 0;

一些 RDBMS 支持 FILTER 语法,这使事情更清晰

HAVING COUNT(*) FILTER (WHERE year = 2020) > 0
   AND COUNT(*) FILTER (WHERE year = 2021) > 0

另请注意,并非每个 RDBMS 都支持 bool 列,也不是所有将 yes 识别为 true 的 RDBMS

【讨论】:

以上是关于SQL -- WHERE、GROUP BY、HAVING 查询的主要内容,如果未能解决你的问题,请参考以下文章

SQL里面group by 语句和WHERE的区别,高手进

sql语句select group by order by where一般先后顺序

sql语句select group by order by where一般先后顺序

sql语句select group by order by where一般先后顺序

SQL中where和group by可以连用吗?having算是对检索条件的补充吗?

SQL中where和group by可以连用吗?having算是对检索条件的补充吗?