常见的SQL编程题
常见的sql题目
1. 查找不在表里的数据
2. 查找第N高的分数
3. 分组排序
4. 连续出现N类问题
5. 打卡表查某人当月连续最长出勤天数
1.有两个表A和B,以id关联,查找在A中但是不在B中的数据
1 2 3 4 5 6 7 8 9 10 11 | 方案a:使用 left join select A.id from A left join B on A.id = B.id where B.id is null 方案b:使用 not exists select A.id from A where not exists ( select 1 from B where A.id = B.id) 方案c:使用 not in select A.id from A where A.id not in ( select id from B) |
2. 有一个课程分数表,score,cource,id(学生id),查找某门课程第N高的分数或者学生, 如果没有需要返回null值
1 | select ifnull (( select distinct score from A order by score desc limit 1 offset n-1), null ) as theNTopScore |
3. 分数排名(三种规则 1134 / 1234 / 1123)使用窗口函数
-- 仅根据分数排名
select score, rank() over(partition by course ORDER by score desc) as 'Rank' FROM table;
-- 根据课程分组,分数排名
select score, rank() over(ORDER by score desc) as 'Rank' FROM table;
4. 有N个相同成绩的分数
select score from table group by score having count(*) = N
-- having: 对group by产生的分组进行筛选
5. 有一个打卡表t_user_sign, 有主键id(自增),有用户id,有打卡时间sign_time
表结构和数据,这里简化一下就直接使用date类型,并且每个人每天最多一条记录
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | CREATE TABLE t_user_sign ( id int (11) not null AUTO_INCREMENT COMMENT '主键' , user_id varchar (255) DEFAULT NULL COMMENT '用户id' , sign_time date NOT NULL COMMENT '打卡时间' , PRIMARY KEY (id) ); INSERT INTO t_user_sign (user_id, sign_time) VALUES ( '1' , '2024-03-01' ),( '1' , '2024-03-02' ),( '1' , '2024-03-03' ),( '1' , '2024-03-04' ), ( '1' , '2024-03-06' ),( '1' , '2024-03-07' ),( '1' , '2024-03-08' ),( '1' , '2024-03-09' ),( '1' , '2024-03-10' ), ( '1' , '2024-03-15' ),( '1' , '2024-03-16' ),( '1' , '2024-03-17' ), ( '2' , '2024-03-02' ),( '2' , '2024-03-03' ),( '2' , '2024-03-04' ), ( '2' , '2024-03-06' ), ( '2' , '2024-03-15' ),( '2' , '2024-03-16' ), ( '2' , '2024-03-20' ); |
思路:先对某个人的打卡记录排序得到一个序号,用打卡时间减去序号能得到一个日期,日期相同代表连续打卡,再分组求和
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | <br> -- 1.使用窗口函数ROW_NUMBER求出这个用户的打卡时间和按时间升序的序号row_num SELECT sign_time, ROW_NUMBER() over( order by sign_time) as row_num from t_user_sign where user_id= '1' and sign_time >= '2024-03-01' -- 2. 练习使用date_sub函数修改日期 SELECT sign_time, date_sub(sign_time, INTERVAL 2 DAY ) as label_date from t_user_sign where user_id= '1' and sign_time >= '2024-03-01' -- 3. 使用date_sub和序号,日期减去序号得到的值label_date,如果label_date相同,则代表连续打卡 SELECT a.sign_time,DATE_SUB(t1.sign_time, INTERVAL t1.row_num DAY ) as label_date FROM ( SELECT sign_time, ROW_NUMBER() over( order by sign_time) as row_num from t_user_sign where user_id= '1' and sign_time >= '2024-03-01' ) t1 -- 4. 对label_date进行分组count,代表连续打卡的天数 SELECT t2.label_date, COUNT (t2.label_date) AS days FROM ( select DATE_SUB(t1.sign_time, INTERVAL t1.row_num DAY ) as label_date FROM ( SELECT sign_time, ROW_NUMBER() over( order by sign_time) as row_num from t_user_sign where user_id= '1' and sign_time >= '2024-03-01' ) t1 ) t2 GROUP BY t2.label_date -- 5. 取出最大的一个天数 SELECT t3.days FROM ( SELECT t2.label_date, COUNT (t2.label_date) AS days FROM ( SELECT DATE_SUB(t1.sign_time, INTERVAL t1.row_num DAY ) as label_date FROM ( SELECT sign_time, ROW_NUMBER() over( order by sign_time) as row_num from t_user_sign where user_id= '1' and sign_time >= '2024-03-01' ) t1 ) t2 GROUP BY t2.label_date) t3 ORDER BY t3.days desc LIMIT 1<br><br><br> |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理