今天来正式的对我的MySQL的刷题来做一做总结,方便以后复习时的复盘,不过本人对MySQL的认识
很浅,所以刷起题来估计也很吃力,一些东西也忘得差不多了,不过就当边做题边复习了。
第一题 1965. 丢失信息的雇员
题意 :表: Employees
+-------------+---------+ | Column Name | Type | +-------------+---------+ | employee_id | int | | name | varchar | +-------------+---------+ employee_id 是这个表的主键。 每一行表示雇员的id 和他的姓名。
表: Salaries
+-------------+---------+ | Column Name | Type | +-------------+---------+ | employee_id | int | | salary | int | +-------------+---------+ employee_id is 这个表的主键。 每一行表示雇员的id 和他的薪水。
写出一个查询语句,找到所有 丢失信息 的雇员id。当满足下面一个条件时,就被认为是雇员的信息丢失:
雇员的 姓名 丢失了,或者 雇员的 薪水信息 丢失了,或者返回这些雇员的id employee_id , 从小到大排序 。
这一题还是相当简单的,只是简单的查询结合union即可得出答案,顺便提一提 union 与 union all的区别,union会返回联合的表的并集,但是不会放回重复项,但是union all会返回重复项,union会对处理后的数据进行排序处理从而达到去重的目的。
select employee_id from employees where employee_id not in (select employee_id from salaries) union select employee_id from salaries where employee_id not in (select employee_id from employees) order by employee_id
评论区发现的一种不错的解法
with tmp as( select employee_id from employees union all select employee_id from salaries ) select employee_id from tmp t group by 1 having count(1)=1 order by 1
这种是根据union all自带重复的特性,抽取那些没有重复输出的数据项就是答案。
第二题 1407. 排名靠前的旅行者
题意 :表:Users
+---------------+---------+ | Column Name | Type | +---------------+---------+ | id | int | | name | varchar | +---------------+---------+ id 是该表单主键。 name 是用户名字。
表:Rides
+---------------+---------+ | Column Name | Type | +---------------+---------+ | id | int | | user_id | int | | distance | int | +---------------+---------+ id 是该表单主键。 user_id 是本次行程的用户的 id, 而该用户此次行程距离为 distance 。
写一段 SQL , 报告每个用户的旅行距离。
返回的结果表单,以 travelled_distance 降序排列 ,如果有两个或者更多的用户旅行了相同的距离, 那么再以 name 升序排列 。
这道题的题意也是比较明显的,先根据旅行的距离进行降序排序,在对首字母按照字母表进行升序排序,但是我傻傻的以为要专门把首字母抽出来进行排序,但其实只需直接对姓名进行排序即可 = =,接下来的思路就很明显了。
SELECT u.name,IFNULL(SUM(r.distance),0) travelled_distance FROM users u LEFT JOIN rides r ON u.id = r.user_id GROUP BY r.user_id ORDER BY travelled_distance DESC, u.name ASC
这里的答案用到了一个嵌套复合函数,很牛,优雅的计算了总和用于后面的排序,学到了。
对了,这里的IFNULL和coalesce的用法非常类似,都是对数据的值是否为空进行判断和对应的赋值处理。
第三题 1084. 销售分析III
题意:Table: Product
+--------------+---------+ | Column Name | Type | +--------------+---------+ | product_id | int | | product_name | varchar | | unit_price | int | +--------------+---------+ Product_id是该表的主键。 该表的每一行显示每个产品的名称和价格。
Table: Sales
+-------------+---------+ | Column Name | Type | +-------------+---------+ | seller_id | int | | product_id | int | | buyer_id | int | | sale_date | date | | quantity | int | | price | int | +------ ------+---------+ 这个表没有主键,它可以有重复的行。 product_id 是 Product 表的外键。 该表的每一行包含关于一个销售的一些信息。
编写一个SQL查询,报告2019年春季才售出的产品。即仅在2019-01-01至2019-03-31(含)之间出售的商品。
以 任意顺序 返回结果表。
这道题的题意也非常明显,对多表联合进行了简单的考察,同时也
使用了判断式的聚合函数sum()判断
是否存在满足条件的情况,存在的话返回 1 ,不存在返回 0,其余的话就很明显了。
SELECT p.product_id,product_name FROM sales s,product p WHERE s.product_id=p.product_id GROUP BY p.product_id HAVING SUM(s.sale_date < '2019-01-01')=0 AND SUM(s.sale_date>'2019-03-31')=0;
也可以使用using进行等值连接(对应属性的名称必须相同)进行连接后直接判断。
select product_id, product_name from Sales join Product using(product_id) group by product_id having sum(sale_date between "2019-01-01" and "2019-03-31") = count(sale_date)
第四題 1890. 2020年最后一次登录
题意:表: Logins
+----------------+----------+ | 列名 | 类型 | +----------------+----------+ | user_id | int | | time_stamp | datetime | +----------------+----------+ (user_id, time_stamp) 是这个表的主键。 每一行包含的信息是user_id 这个用户的登录时间。
编写一个 SQL 查询,该查询可以获取在 2020 年登录过的所有用户的本年度 最后一次 登录时间。结果集 不 包含 2020 年没有登录过的用户。
返回的结果集可以按 任意顺序 排列。
题意明显:提取时间戳的年判断是否为2020,然后再输出对应的日期即可
SELECT user_id, max(time_stamp) last_stamp FROM Logins WHERE year(time_stamp) = 2020 GROUP BY user_id
也可以使用通配符进行判断和取值。
select user_id,max(time_stamp)last_stamp from logins where time_stamp like "2020%" group by user_id
第五题 197. 上升的温度
题意:表: Weather
+---------------+---------+ | Column Name | Type | +---------------+---------+ | id | int | | recordDate | date | | temperature | int | +---------------+---------+ id 是这个表的主键 该表包含特定日期的温度信息
编写一个 SQL 查询,来查找与之前(昨天的)日期相比温度更高的所有日期的 id 。
返回结果 不要求顺序 。
这里学到了一个函数dateDiff(date1,date2),这里可以计算相邻日期的日期差值,从而解题。
select a.Id from Weather as a join Weather as b on a.Temperature > b.Temperature and dateDiff(a.RecordDate,b.RecordDate) = 1