从题目看,需要先计算(此处是分组求和),再根据计算结果查询。需要用到嵌套子查询。
计算<=某一时刻时,q这一列的总和。
考点:
- 嵌套查询
- 聚合函数
SELECT
p
FROM
(SELECT
p,SUM(q) AS s
FROM
`A`
WHERE t <= '2022-05-22 21:35:37'
GROUP BY
p
HAVING
s = 0
)
AS t1
或者不用Having用where
SELECT
p
FROM
(SELECT
p,SUM(q) AS s
FROM
`A`
WHERE t <= '2022-05-22 21:35:37'
GROUP BY
p
)
AS t1
WHERE s = 0;
纠错总结:
- mysql5.7.5之后的sql node的原因,聚合函数要带上group by。可以关闭这个检查模式,或者就遵循这个规则写sql
- 如果产生了派生表格,应当为他取别名(例子中的t1)
进行嵌套查询的时候子查询出来的的结果是作为一个派生表来进行上一级的查询的,所以子查询的结果必须要有一个别名
报错解决:
In aggregated query without GROUP BY, expression #2 of SELECT list contains nonaggregated column 'myemployees.employees.department_id'; this is incompatible with sql_mode=only_full_group_by
解决方法:把select的列中,没有在聚合函数的列进行group by
关于select其他列时,聚合函数要求group by其他列的逻辑猜想
聚合函数(求和等)如果不进行分组,就默认对所有记录的该列进行求和,得到的记录应该只有一行。此时自然没有group by的必要
select sum(列名) from 表名
/*这也是很多人学习sum函数时的经典语句 */
但如果我们还要select其他列,其他列可能会有许多行许多符合查询条件的记录;但sum的结果只有一行,这个时候会如何呢?
如果不开启上面说的ONLY_FULL_GROUP_BY
的sql node模式,那么我们select出来的结果将仍然只有一行;其他列
的其余记录将会被舍去
select 其他列, sum(列名) from 表名
舍弃其他行记录,并且仍然是求总和的结果通常不是我们想看到的,这条Sql语句此时合法但没有意义,真有需要时完全可以用其他更符合的sql语句拿到这样的结果。这也是为什么很多数据库支持ONLY_FULL_GROUP_BY
检查模式检查语法,通过要求select的列必须在聚合函数或是group by中来避免写出这样的Sql语句
但我曾经在某些书上看到过这种写法,,不知道sql标准官方是否允许这种写法,它虽然没有现实意义,但确实是符合语法的
我们的需求(也是本题的需求)是“分组求和”。在实现这个需求的同时,自然而然的符合了ONLY_FULL_GROUP_BY
模式的语法
select 其他列, sum(列名) from 表名 group by 其他列
为了符合ONLY_FULL_GROUP_BY
,也为了实现分组查询,把select的其他列也要在group中写明,据此进行分组。这样正好使select的其他结果个sum分组的结果相匹配了,也不会舍弃一些记录了。
总结:语法上说,不是聚合函数必须gruop by或group by必须要求聚合函数
而是在使用聚合函数
又select其他列的情况下,ONLY_FULL_GROUP_BY
模式会有刚才提到的更严格的语法要求。
运行聚合函数时,若已分组就会对每个分组进行聚合运算,对没分组的全部计算并舍弃其余行;
若全部没有分组,那就计算所有行,并舍弃第一行外的所有行
查阅资料:
mysql报错:IN AGGREGATED QUERY WITHOUT GROUP BY, EXPRESSION #2 OF SELECT LIST CONTAINS NONAGGREGATED
其他笔记
聚合函数可以应用于SELECT 查询语句的 GROUP BY 子句的HAVING子句中,但不可用于WHERE语句中,因为WHERE是对逐条的行记录进行筛选。
-
各种字句的运行顺序。
-
查询某个时间前的记录:直接小于号,时间可以用字符串