【数据库与SQL】力扣刷题SQL篇(1)

本文提供了一系列SQL实战技巧,包括如何组合两个表、查找第二高及第N高的薪水、处理连续出现的数据等问题。通过多种方法和技巧,帮助读者更好地理解和掌握SQL查询。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

力扣SQL题目整理

1.组合两个表

在这里插入图片描述

在这里插入图片描述

select p.FirstName, p.LastName, a.City, a.State
from Person as P
left join Address as a
on p.PersonId = a.PersonId   

多表连接
在这里插入图片描述

2.第二高的薪水

在这里插入图片描述
方法一

第二高,小于最大值,筛选出来后在求最大值

select max(Salary) as SecondHighestSalary 
from Employee 
where Salary <(
    select max(Salary)
    from Employee
);

方法二

使用关键字distinct,order by,limit,ifnull

select ifnull(
   (select distinct Salary
    from Employee
    order by Salary desc 
    limit 1,1),null
) as SecondHighestSalary 

limit 和 limit offset区别

下面是几种SQL语句limit使用方法:
1select * from Customer LIMIT 10;--检索前10行数据,显示1-10条数据;
2select * from Customer LIMIT 1,10;--检索从第2行开始,取10条id记录,共显示id为2....11;
3select * from Customer limit 5,10;--检索从第6行开始取10条数据,共显示id为6,7....15;
4select * from Customer limit 6,10;--检索从第7行开始取10条记录,显示id为7,8...16。
Limit的作用是获取一表前几条或中间某几行数据,注意只在MySQL中起作用。Limit用法:limit 起始下标m,长度n ,m是记录开始的index,默认从0开始,表示第一条记录,n是指从第m+1条开始,取n条。

所以

limit 1,1 表示从第二行开始,取1条数据,即第二行
LIMIT a  OFFSET b
#表示跳过b个数据,取a个数据
#参数a表示读取a条数据
#参数b表示跳过b个数据
eg:
SELECT * FROM table LIMIT 2 OFFSET 1;  //跳过1条数据读取2条数据,即读取2-3条数据
eg5:
SELECT * FROM table LIMIT 2,1;  //跳过2条数据读取1条数据,即读取3条数据
SELECT * FROM table LIMIT 2 OFFSET 1;  //跳过1条数据读取2条数据,即读取2-3条数据

3.第N高的薪水

在这里插入图片描述

知识点:

1.自定义函数

CREATE FUNCTION 函数名(参数) 
RETURNS 返回值类型
BEGIN
  SQL语句块
END;

注意,函数注重返回结果,只有一个返回值。

2.SQL中IF ELSE作为流程控制语句使用的格式:

IF 条件判断1 THEN 结果1;
[ELSEIF 条件判断2 THEN 结果2;]
[ELSEIF 条件判断3 THEN 结果3;]
...
[ELSE 结果n;]  
END IF;

注意:每一句末尾都要加英文分号“;”。

3.LIMIT的使用

limit里的参数不能运算,即limit N - 1, 1是非法的。所以要提前设置变量N自减。

4.MySQL中IFNULL函数的使用

(1) IF(expr1,expr2,expr3)
如果expr1的值为TRUE,则返回expr2的值;如果expr1的值为FALSE,则返回expr3的值。

(2) ISNULL(expr)
如果expr的值为NULL,则返回1;否则返回0(3) NULLIF(expr1,expr2)
如果expr1 = expr2成立,则返回值为NULL;否则返回值为expr1的值。

limit start, count。其中start的显示值是从start+1开始的。但此处输入不能是计算式,比如:N-1
在这里插入图片描述

CREATE FUNCTION getNthHighestSalary(N INT) RETURNS INT
BEGIN
  SET N = N-1;
  IF N <0 THEN
  RETURN NULL;
  ELSE
  RETURN (
      # Write your MySQL query statement below.
      SELECT IFNULL(
          (SELECT DISTINCT Salary from Employee
      order by Salary DESC LIMIT N,1),NULL
     )
      AS getNthHighestSalary
  );
  END IF;
END
CREATE FUNCTION getNthHighestSalary(N INT) RETURNS INT
BEGIN
    # 定义变量
    declare p int;
    # 变量赋值
    set p=n-1;
    IF N <0 THEN
    RETURN NULL;
    ELSE    	
    RETURN (      
        select ifnull(
                        (
                        # LIMIT a OFFSET b 方法  
                        #select distinct salary 
                        #from employee 
                        #order by salary desc 
                        #limit 1 OFFSET P

                        # LIMIT a,b 方法
                        select distinct salary 
                        from employee 
                        order by salary desc 
                        limit P,1
                        
                        ),null) as SecondHighestSalary 
        );     
END

方法二
利用窗口函数 dense_rank生成工资排表和rank的subquery,然后根据rank直接输出

CREATE FUNCTION getNthHighestSalary(N INT) RETURNS INT
BEGIN
  RETURN (
      # Write your MySQL query statement below.
      select distinct Salary from
      (select id, dense_rank() over(order by Salary desc) as 'rank', Salary from employee) as r
      where  r.rank = N
  );
END

4.分数排名

在这里插入图片描述
在这里插入图片描述
【Hive学习笔记】窗口函数

SELECT Score, 
    DENSE_RANK() OVER(ORDER BY Score DESC) AS 'Rank'
FROM Scores

5.连续出现的数字

在这里插入图片描述
在这里插入图片描述

这道题引用力扣中的回答

方法一,自连接
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
方法二,自连接

select distinct a.num as ConsecutiveNums
from logs a, logs b, logs c
where a.num = b.num and b. num = c.num
and a.id = b.id - 1 and b.id = c.id -1;

方法三,利用窗口函数LAG()与LEAD()

在这里插入图片描述

# Write your MySQL query statement below
select distinct a.n1 as ConsecutiveNums
from
(select Num as n1,
lead(Num,1) over() as n2,
lead(Num,2) over() as n3
from Logs) as a  
where a.n1=a.n2 and a.n2=a.n3

著作权归作者所有
链接:https://leetcode-cn.com/problems/consecutive-numbers/solution/biao-de-zi-lian-jie-de-gao-xiao-ti-dai-l-tg0m/

with t as (
    select Id, Num,
		lag(Num) over () as 'L1',
		lead(Num) over () as 'L2'
	from Logs
)

select distinct Num as ConsecutiveNums
from t
where Num = L1 and Num = L2;

方法四,利用变量处理

在这里插入图片描述

select distinct num as ConsecutiveNums
from (
	select id, num, if(num=@i,@p:=@p+1,@p:=1) as rnk, @i:=num
	from logs, (select @i:=0, @p:=0) as n) as t
where rnk>=3

著作权归作者所有
链接:https://leetcode-cn.com/problems/consecutive-numbers/solution/180-lian-xu-chu-xian-de-shu-zi-bian-lian-js5p/

最后,get大佬级别的解题思路

方法五,窗口函数 row_number()

不仅考虑到了n次,还考虑到了ID不连续

在这里插入图片描述

SELECT DISTINCT Num FROM (
SELECT Num,COUNT(1) as SerialCount FROM 
(SELECT Id,Num,
row_number() over(order by id) -
ROW_NUMBER() over(partition by Num order by Id) as SerialNumberSubGroup
FROM ContinueNumber) as Sub
GROUP BY Num,SerialNumberSubGroup HAVING COUNT(1) >= 3) as Result

详细步骤:https://leetcode-cn.com/problems/consecutive-numbers/solution/sql-server-jie-fa-by-neilsons/

SQL中的连续问题

在这里插入图片描述

解答

参考:SQL连续性问题

select TEAM, Y , Y-rnk as grp
from (
	select TEAM,Y,row_number() over(partition by TEAM order by Y) rnk 
	from t) as t1

在这里插入图片描述

select TEAM,min(Y) S,max(Y) E
from (
    select TEAM , Y ,Y-rnk as grp
    from (
        select TEAM,Y,row_number() over(partition by TEAM order by Y) rnk 
        from t
        ) as t1 
) t2
group by grp,TEAM 
having count(*)>1 
order by max(Y);

SQL解决连续n天登录问题(时间与排序相减)

引用:https://blog.csdn.net/m0_47698998/article/details/113886319

详情移步引用文章,这里只做例子进行学习
在这里插入图片描述
问题:求连续登陆3天及以上的用户

在这里插入图片描述
在这里插入图片描述

sql连续登录3天以上用户_SQL窗口函数轻松解决连续N天购买用户问题

引用例子:https://blog.csdn.net/weixin_33198642/article/details/113320660?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_title-0&spm=1001.2101.3001.4242
在这里插入图片描述
求连续登录3天以上用户


SELECT * 
FROM
 (SELECT *,LEAD(orderdate,2)over(PARTITION by name1 ORDER BY orderdate)date3 FROM ord) a 
WHERE DATEDIFF(date1,orderdate)=2

计算每位客户相邻两次购物的时间差

请参考引用例子文章


另外

SQL经典面试题 - 连续3天登录用户,终于会了!

### 力扣平台上的SQL数据库练习力扣(LeetCode)提供了一系列丰富的SQL练习目,旨在帮助开发者提升查询编写能力并深入理解关系型数据库操作。以下是精心挑选的一组50道SQL目集合: #### 基础级问 这些问主要针对初学者设计,涵盖了基本的选择、过滤以及简单的聚合函数应用。 1. **176. Second Highest Salary** 查询第二高的薪水。 2. **183. Customers Who Never Order** 找出从未下过订单的客户列表。 3. **595. Big Countries** 列举面积大于3百万平方公里或人口超过2亿的大国名称及其对应的区域和人口数。 4. **175. Combine Two Tables** 将两个表按照给定条件连接起来显示结果集。 ... #### 中等级问 这类问适合有一定经验的学习者挑战自我,涉及更复杂的联结、子查询及窗口函数等内容。 1. **184. Department Highest Salary** 查找各部门最高薪资员工的信息。 2. **177. Nth Highest Salary** 实现获取第N高工资的功能。 3. **579. Find Cumulative Salary of an Employee** 计算每位雇员累计到当前月份为止所获得的所有报酬总额。 4. **580. Count Student Number in Departments** 统计各系学生人数情况。 ... #### 高阶级问 对于希望进一步深化技能的人来说,这些难提供了很好的实践机会,通常涉及到多张表格之间的复杂关联分析。 1. **608. Tree Node** 解决树形结构数据存储模式下的节点分类识别问。 2. **612. Shortest Distance in a Plane** 寻找平面上最近两点间的最短距离。 3. **615. Average Salary: Departments VS Company** 对比部门平均薪酬公司整体水平差异状况。 4. **627. Swap Salary** 编写交换性别对应薪资数额的更新语句。 ... 为了更好地准备面试或者巩固知识点,建议从简单入手逐步过渡至较难的部分。每完成一道习都应仔细回顾解法思路,并尝试优化性能以达到最佳效果[^1]。 ```sql -- 示例代码片段:查找第二高的薪水 SELECT MAX(Salary) AS SecondHighestSalary FROM Employees WHERE Salary != (SELECT MAX(Salary) FROM Employees); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值