Leetcode刷题手札——MySQL


长期没接触SQL,忘记的一干二净,本篇仅作为「个人刷题笔记」,记录一些简单的SQL学习过程。欢迎指正批评。

SQL

Leetcode-584. 寻找用户推荐人 SQL 简单(Simplist)

Question

在这里插入图片描述
Answer:

select name 
from customer 
where referee_id is NULL OR referee_id <> 2;

Note:

  1. is NULL VS = NULL :
    在SQL中,NULL是一种特有的数据类型,其等价于没知有任何值、是未知数。NULL与0、空道字符串、空格都不同,只有非ANSI SQL标准中data=NULL等同于data IS NULL。
    答案链接
  2. 不等于可以使用 <>

Leetcode 586. 订单最多的客户 SQL 简单

Question:
在这里插入图片描述
Answer:

select customer_number
from Orders 
Group by customer_number
having count(order_number) = (
    select max(sum1) 
    from (
        select customer_number, count(order_number) as sum1
        from Orders
        group by customer_number
    )tmp
);

【Note】group by的相关知识点:
group by:分组查询,一般和聚合函数配合使用。
【使用原则】select 后面的列中,没有使用聚合函数的列,必须出现在 group by 后面!!
【注意事项】

  1. group by 必须在where之后,having之前。
  2. where 子句的作用是在对查询结果进行分组前,将不符合where条件的行去掉,即在分组之前过滤数据,条件中不能包含聚组函数,使用where条件显示特定的行。(过滤行)
  3. having 子句的作用是筛选满足条件的组,即在分组之后过滤数据,经常包含聚组函数,使用having 条件显示特定的组,也可以使用多个分组标准进行分组。(过滤分组)
  4. 多个NULL将被分在一组。
  5. 使用WITH ROLLUP可得到每个分组以及其汇总级别的值。
  6. ORDER BY放在HAVING后面。
  7. SELECT-FROM-WHERE-GROUP BY-HAVING-ORDER BY-LIMIT

Leetcode-181. 超过经理收入的员工 SQL 简单(Simplist)

Question
在这里插入图片描述
Ans

方法1:自链接

select a.name as Employee
from Employee as a, Employee as b
where a.Salary > b.Salary and a.managerId=b.id;

方法2:子链接

select e.name as Employee
from Employee as e
where Salary>(select Salary from Employee where id=e.managerId);

Leetcode-180. 连续出现的数字(中等)

Question
在这里插入图片描述
我的想法是建立一个自连接的表,配合子查询进行操作

select c.Num as ConsecutiveNums
from (
    select l.Num, count(l.Num) as couNum
    from Logs l, Logs l1
    where (l.id = l1.id-1 OR l.id = l1.id-2) AND (l.num = l1.num)
) c
where c.couNum >= 3;

但问题就出现在,当出现两个连续数字的时候,会满足where的条件然后返回。
于是看了官方的解答,明白了可以使用三个表的自连接,配合distinct使用

select distinct l.Num as ConsecutiveNums
from Logs l, Logs l1, Logs l2
where 
l.id = l1.id-1 
and l1.id = l2.id-1
and l.num = l1.num 
and l1.num = l2.num

目前对运行速度还没有改进要求,之后再来填坑。

Leetcode-182. 查找重复的电子邮箱 (简单)

在这里插入图片描述

最基础的题目,几乎是我在学习SQL之后第一道写的题目。但是发现自己好像每次都用自连接来解决问题,导致真的会很慢:

SELECT distinct p1.Email as Email
FROM Person p1, Person p2 
WHERE p1.Id<p2.Id 
AND p1.Email=p2.Email

查看评论区后整理:
方法1:自连接
方法2:having+count聚合

select Email from Person group by Email having count(Email) > 1;

方法3:子查询

select Email from (select count(1) as t, Email from Person group by Email) r where r.t > 1;

具体哪个快呢?
1略快于2,快于3

Leetcode-1084. 销售分析III(简单)

编写一个SQL查询,报告2019年春季才售出的产品。即仅在2019-01-01至2019-03-31(含)之间出售的商品。
在这里插入图片描述

# My code
select z.product_id, z.product_name
from (
    select p.product_id, p.product_name, max(s.sale_date) max_d, min(s.sale_date) min_d
    from Product p , Sales s
    where p.product_id = s.product_id
    group by p.product_id) z
where DATE(z.max_d) <= '2019-03-31' AND DATE(z.min_d)>='2019-01-01';
# from comment
select p.product_id,p.product_name
from product p right join sales s
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';
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值