力扣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使用方法:
1、select * from Customer LIMIT 10;--检索前10行数据,显示1-10条数据;
2、select * from Customer LIMIT 1,10;--检索从第2行开始,取10条id记录,共显示id为2....11;
3、select * from Customer limit 5,10;--检索从第6行开始取10条数据,共显示id为6,7....15;
4、select * 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的值。
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.分数排名
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
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天购买用户问题
SELECT *
FROM
(SELECT *,LEAD(orderdate,2)over(PARTITION by name1 ORDER BY orderdate)date3 FROM ord) a
WHERE DATEDIFF(date1,orderdate)=2
计算每位客户相邻两次购物的时间差
请参考引用例子文章
另外