SQL笔试题总结:求某时刻已销售完毕的商品编号

在这里插入图片描述从题目看,需要先计算(此处是分组求和),再根据计算结果查询。需要用到嵌套子查询。
计算<=某一时刻时,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是对逐条的行记录进行筛选。

  • 各种字句的运行顺序。

  • 查询某个时间前的记录:直接小于号,时间可以用字符串

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,那我们假设有一个销售表 sales,其中包含以下字段: - id:销售记录的唯一标识符 - product_id:商品的唯一标识符 - sale_date:销售日期,格式为 YYYY-MM-DD - sale_amount:销售金额 我们可以使用如下 SQL 语句来查询每个月商品的销售额同环比: ```sql SELECT DATE_FORMAT(s1.sale_date, '%Y-%m') AS month, SUM(s1.sale_amount) AS current_month_sales, SUM(s2.sale_amount) AS last_month_sales, SUM(s1.sale_amount) / SUM(s2.sale_amount) - 1 AS mom_growth_rate, SUM(s1.sale_amount) / SUM(s3.sale_amount) - 1 AS yoy_growth_rate FROM sales s1 LEFT JOIN sales s2 ON DATE_FORMAT(s1.sale_date, '%Y-%m') = DATE_FORMAT(DATE_SUB(s2.sale_date, INTERVAL 1 MONTH), '%Y-%m') AND s1.product_id = s2.product_id LEFT JOIN sales s3 ON DATE_FORMAT(s1.sale_date, '%Y-%m') = DATE_FORMAT(DATE_SUB(s3.sale_date, INTERVAL 1 YEAR), '%Y-%m') AND s1.product_id = s3.product_id GROUP BY DATE_FORMAT(s1.sale_date, '%Y-%m') ``` 这个 SQL 语句使用了三个子查询,分别对应当前月、上月和去年同期的销售数据。通过 LEFT JOIN 连接这三个子查询,我们可以得到每个月的销售额、上月销售额、去年同期销售额,以及同环比增长率。其中,同比增长率计算方式为 `(当前月销售额 / 去年同期销售额) - 1`,环比增长率计算方式为 `(当前月销售额 / 上月销售额) - 1`。最后,我们使用 DATE_FORMAT 函数将销售日期格式化为年月,然后按月份分组,即可得到每个月的同环比销售数据。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值