力扣的SQL
题外话
昨天看到大厂的数据开发面试题,感觉好陌生。然后今天早上又看到一个SQL编程大赛,震惊到我了。我就在想,力扣上的题是不是太基础了,要不要看看会员的SQL题
1075-project-employees-i
https://leetcode.com/problems/project-employees-i/description/
请写一个 SQL 语句,查询每一个项目中员工的 平均 工作年限,精确到小数点后两位。
以 任意 顺序返回结果表。
查询每一个项目中员工的 平均 工作年限
select p.project_id as project_id, round(avg(e.experience_years), 2) as average_years
from Employee e
join Project p on e.employee_id = p.employee_id
group by p.project_id
1084-sales-analysis-iii
https://leetcode.com/problems/sales-analysis-iii/description/
2025年6月14日 星期六
-- 其实题目要求“仅在2019-01-01至2019-03-31之间出售的商品”翻译过来就是“所有售出日期都在这个时间内”,也就是“在这个时间内售出的商品数量等于总商品数量”,这样就不难写出这个语句# 作者:喜刷刷
# 链接:https://leetcode.cn/problems/sales-analysis-iii/solutions/2119386/zuo-wei-ru-men-ti-zui-hou-yi-dao-huan-sh-wmof/
-- leetcode
SELECT DISTINCT p.product_id, p.product_name
FROM Sales s
LEFT JOIN Product p ON p.product_id = s.product_id
GROUP BY p.product_id
HAVING MIN(sale_date) >= '2019-01-01' AND MAX(sale_date) <= '2019-03-31';
非聚合的字段要出现在group
select s.product_id, product_name
from sales s join Product P on s.product_id = P.product_id
group by s.product_id
having min(sale_date) >= 2019-01-01 and max(sale_date) <= 2019-03-31
你遇到的错误是 MySQL 的 ONLY_FULL_GROUP_BY
模式导致的。这个模式要求 SELECT
里的所有非聚合字段必须在 GROUP BY
中,或者是函数依赖于 GROUP BY
的字段。
你这个查询:
select s.product_id, product_name
from sales s join Product P on s.product_id = P.product_id
group by s.product_id
having min(sale_date) >= 2019-01-01 and max(sale_date) <= 2019-03-31
问题是 product_name
没有在 GROUP BY
中,也没有用聚合函数包裹。
解决办法有以下几种:
1. 把 product_name
加入 GROUP BY
select s.product_id, product_name
from sales s join Product P on s.product_id = P.product_id
group by s.product_id, product_name
having min(sale_date) >= '2019-01-01' and max(sale_date) <= '2019-03-31'
如果 product_name
对应的 product_id
是唯一确定的(通常是这样),这也是合理的。
2. 使用聚合函数包裹 product_name
(比如 MIN
或 MAX
)
select s.product_id, MIN(product_name) as product_name
from sales s join Product P on s.product_id = P.product_id
group by s.product_id
having min(sale_date) >= '2019-01-01' and max(sale_date) <= '2019-03-31'
如果每个 product_id
对应唯一 product_name
,MIN
和 MAX
取出来是一样的。
3. 关闭 ONLY_FULL_GROUP_BY
(不推荐)
在会话里执行:
SET sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));
然后再执行你的查询。
1141-user-activity-for-the-past-30-days-i
https://leetcode.com/problems/user-activity-for-the-past-30-days-i/description/
select activity_date as day, count(distinct user_id) as active_users
from Activity
where datediff('2019-07-27', activity_date) < 30 and datediff('2019-07-27', activity_date) >= 0
group by 1
group by 1是什么意思
在 SQL 查询中,GROUP BY 1
是一种简写形式,表示按 第一个选择的字段 来分组。具体来说,数字 1
对应于 SELECT 子句中列出的第一个字段。
示例:
SELECT department, COUNT(*)
FROM employees
GROUP BY 1;
在这个例子中,GROUP BY 1
表示按 SELECT 子句中的第一个字段 department
来进行分组,相当于写成:
GROUP BY department;
这种写法是一种简便方式,尤其在查询中涉及多个字段时,避免重复写出字段名。
1148-article-views-i
https://leetcode.com/problems/article-views-i/description/
select distinct author_id as id
from Views
where author_id = viewer_id
order by id
1158-market-analysis-i
https://leetcode.com/problems/market-analysis-i/description/
好乱啊
select user_id AS buyer_id, join_date,count(order_date) as orders_in_2019
from Users
left join Orders on user_id = buyer_id and YEAR(order_date) = '2019'
group by user_id
order by user_id
1164-product-price-at-a-given-date
https://leetcode.com/problems/product-price-at-a-given-date/description/
指定日期的产品价格
-- leetcode
SELECT product_id, 10 AS price
FROM Products
GROUP BY product_id
HAVING MIN(change_date) > '2019-08-16'
UNION ALL
SELECT product_id, new_price AS price
FROM Products
WHERE (product_id, change_date) IN (SELECTproduct_id,MAX(change_date)FROMProductsWHEREchange_date <= '2019-08-16'GROUP BYproduct_id)