MySQL刷题 day04
LC1211 查询结果的质量和占比
知识点:
1.AVG函数的基础语法:
SELECT AVG(column_name)
FROM table_name
[WHERE conditions];
2.注意事项 avg函数的空值处理:若score列全为null , 则会返回 null值
-- 如果 score 列全为 NULL:
SELECT AVG(score) FROM students WHERE class = 'C';
-- 结果为 NULL
3. avg函数的高级用法 AVG后面跟一个条件
1. 原理:布尔值转数值
-
在 MySQL 中,条件表达式(如
rating < 3
)的结果会被隐式转换为 整数:-
真(True) → 转换为
1
-
假(False) → 转换为
0
-
-
因此,
AVG(rating < 3)
实际上是在计算 满足条件的行数占总行数的比例(即1
的平均值)。
比如本题中:
要统计rating 小于 3 占的百分比 , 可以用avg(rating < 3)这样的布尔表达式 , 若条件成立 ,msql会自动将其转化为 1 , 相当于 rating < 3 的行都会认为是 1 , 再加起来 除以行数 , 就是占比了.
本题代码
select
date_format(trans_date , '%Y-%m') as month ,
country ,
count(*) as trans_count ,
count(case when state = 'approved' then 1 end) as approved_count ,
sum(amount) as trans_total_amount ,
sum(case when state = 'approved' then amount else 0 end) as approved_total_amount
from Transactions
group by month , country
select
date_format(trans_date , '%Y-%m') as month
1. 格式符定义
格式符 | 含义 | 示例 |
---|---|---|
%y | 两位年份(00-99) | 2023 → 23 |
%Y | 四位年份(0000-9999) | 2023 → 2023 |
%m | 两位数字月份(01-12) | 12月 → 12 |
%M | 月份英文全名(January-December) | 12月 → December |
2.mysql中各关键词执行顺序
在SQL查询的执行过程中,通常的顺序是从FROM开始,然后是WHERE、GROUP BY、HAVING、SELECT、ORDER BY和LIMIT。
LC1174 即时食物配送
思路
1.先把每位顾客首次下单日期和id查出来 注意要group by 顾客id。作为子表
select customer_id , min(order_date) as first_date from Delivery group by customer_id as first_orders
2.为了获取 顾客期望的配送日期 , 需要将查出来的子表和delivery表连接 ,连接条件为顾客id相同、下单日期一致。
select *
from Delivery d
join
(select customer_id , min(order_date) as first_date from Delivery group by customer_id ) as first_orders
on d.customer_id = first_orders.customer_id and d.order_date = first_orders.first_date
3.按照题意统计百分率即可。
本题知识点:join 和 left join
为什么本题left join 不行?(其实也可以 ,把 count (*) 换成 count(列名即可))
本质在于left join 和 join的逻辑。 join只会连接并返回两张表中满足连接条件的那些行 ,而left join则会完整的返回左表的所有内容 以及满足连接条件的行,不满足连接条件的会自动成为null值,
本题若使用 left join 链接后的结果就会出现许多null值 , 因为d.order_date = first_orders.first_date不满足的的行依然会被保留 , 只是左表不变,右表被替换成null值了
而count(*) 、 count(1)会数出所有的行数 , 而count(列名) 是遇到空行 就跳过