暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

按在地上摩擦面试官mysql之实战八

Java八股文宝典 2021-04-20
443

日常工作中,会遇到大量的sql编写,同样一个逻辑,每个人写的sql会有不同。实战篇会带领大家进行大量的sql练习,希望你自己独立思考,进行sql编写

Q1

牛客的课程订单分析(一)


有很多同学在牛客购买课程来学习,购买会产生订单存到数据库里。

有一个订单信息表(order_info),简况如下:

第1行表示user_id为557336的用户在2025-10-10的时候使用了client_id为1的客户端下了C++课程的订单,但是状态为没有购买成功。

第2行表示user_id为230173543的用户在2025-10-12的时候使用了client_id为2的客户端下了Python课程的订单,状态为购买成功。

。。。

最后1行表示user_id为557336的用户在2025-10-24的时候使用了client_id为1的客户端下了Python课程的订单,状态为没有购买成功。



请你写出一个sql语句查询在2025-10-15以后状态为购买成功的C++课程或者Java课程或者Python的订单,并且按照order_info的id升序排序

01

牛客的课程订单分析(一)

自己思考几分钟,在看下我的思路:

点击空白处查看答案

1. 这题主要就是条件查询,datediff(date1,date2)两个时间的差


SELECT id, user_id,product_name,status,client_id,date

FROM order_info

WHERE DATEDIFF(date , '2025-10-15') >= 1

AND status = 'completed'

AND product_name IN ('C++' , 'Java' , 'Python')

ORDER BY id;



 

Q2

牛客的课程订单分析(二)


有很多同学在牛客购买课程来学习,购买会产生订单存到数据库里。

有一个订单信息表(order_info),简况如下:

第1行表示user_id为557336的用户在2025-10-10的时候使用了client_id为1的客户端下了C++课程的订单,但是状态为没有购买成功。

第2行表示user_id为230173543的用户在2025-10-12的时候使用了client_id为2的客户端下了Python课程的订单,状态为购买成功。

。。。

最后1行表示user_id为557336的用户在2025-10-24的时候使用了client_id为1的客户端下了Python课程的订单,状态为没有购买成功。

请你写出一个sql语句查询在2025-10-15以后,同一个用户下单2个以及2个以上状态为购买成功的C++课程或Java课程或Python课程的user_id,并且按照user_id升序排序

02

牛客的课程订单分析(二)

自己思考几分钟,在看下我的思路:

点击空白处查看答案

1. 先统计满足条件的学生数量

2. 再取数量大于2的学生


SELECT user_id

FROM(SELECT user_id,COUNT(user_id) AS u_n FROM order_info WHERE date > "2025-10-15" AND status = "completed" AND product_name IN("C++","Python","Java")

GROUP BY user_id) AS r_order

WHERE u_n >= 2

ORDER BY user_id;


 

Q3

牛客的课程订单分析(三)


有很多同学在牛客购买课程来学习,购买会产生订单存到数据库里。

有一个订单信息表(order_info),简况如下:

第1行表示user_id为557336的用户在2025-10-10的时候使用了client_id为1的客户端下了C++课程的订单,但是状态为没有购买成功。

第2行表示user_id为230173543的用户在2025-10-12的时候使用了client_id为2的客户端下了Python课程的订单,状态为购买成功。

。。。

最后1行表示user_id为557336的用户在2025-10-24的时候使用了client_id为1的客户端下了Python课程的订单,状态为没有购买成功。


请你写出一个sql语句查询在2025-10-15以后,同一个用户下单2个以及2个以上状态为购买成功的C++课程或Java课程或Python课程的订单信息,并且按照order_info的id升序排序

03

 牛客的课程订单分析(三)

自己思考几分钟,在看下我的思路:

点击空白处查看答案

1. 根据上题可以简单的获取到满足条件的用户

2. 将满足条件的用户作为条件


select * from order_info where user_id in

(select user_id from order_info  where date>"2025-10-15"

 and status = "completed" and product_name in ("Python","C++","Java")

 group by user_id having count(user_id)>=2) and  date>"2025-10-15"

and status = "completed" and product_name in ("Python","C++","Java")


 

Q4

牛客的课程订单分析(四)


有很多同学在牛客购买课程来学习,购买会产生订单存到数据库里。

有一个订单信息表(order_info),简况如下:


第1行表示user_id为557336的用户在2025-10-10的时候使用了client_id为1的客户端下了C++课程的订单,但是状态为没有购买成功。

第2行表示user_id为230173543的用户在2025-10-12的时候使用了client_id为2的客户端下了Python课程的订单,状态为购买成功。

。。。

最后1行表示user_id为557336的用户在2025-10-24的时候使用了client_id为1的客户端下了Python课程的订单,状态为没有购买成功。


请你写出一个sql语句查询在2025-10-15以后,如果有一个用户下单2个以及2个以上状态为购买成功的C++课程或Java课程或Python课程,那么输出这个用户的user_id,以及满足前面条件的第一次购买成功的C++课程或Java课程或Python课程的日期first_buy_date,以及购买成功的C++课程或Java课程或Python课程的次数cnt,并且输出结果按照user_id升序排序

04

牛客的课程订单分析(四)

自己思考几分钟,在看下我的思路:

点击空白处查看答案

1. 查询已购买的日期2025-10-15之后的,课程也满足的

2. 统计满足条件的数量,以及第一次的时间


select user_id,min(`date`) as first_buy_date,count(*) as cnt

from order_info

where `date`>'2025-10-15' and status='completed' and product_name in ('C++','Java','Python')

group by user_id

having count(*)>1

order by user_id;


 

Q5

牛客的课程订单分析(五)


有很多同学在牛客购买课程来学习,购买会产生订单存到数据库里。

有一个订单信息表(order_info),简况如下:


第1行表示user_id为557336的用户在2025-10-10的时候使用了client_id为1的客户端下了C++课程的订单,但是状态为没有购买成功。

第2行表示user_id为230173543的用户在2025-10-12的时候使用了client_id为2的客户端下了Python课程的订单,状态为购买成功。

。。。

最后1行表示user_id为557336的用户在2025-10-24的时候使用了client_id为1的客户端下了Python课程的订单,状态为没有购买成功。


请你写出一个sql语句查询在2025-10-15以后,如果有一个用户下单2个以及2个以上状态为购买成功的C++课程或Java课程或Python课程,那么输出这个用户的user_id,以及满足前面条件的第一次购买成功的C++课程或Java课程或Python课程的日期first_buy_date,以及满足前面条件的第二次购买成功的C++课程或Java课程或Python课程的日期second_buy_date,以及购买成功的C++课程或Java课程或Python课程的次数cnt,并且输出结果按照user_id升序排序

05

牛客的课程订单分析(五)

自己思考几分钟,在看下我的思路:

点击空白处查看答案

1. 利用窗口函数找到用户user_id和日期

2. 再利用case when 找到第一次和第二次购买的时间

3. 同时一个下两单的人


select user_id,

    min(case when n=1 then date end) as first_buy_date,

    min (case when n=2 then date end) as second_buy_date,

    sum(1) as cnt

from(

    select user_id, date, row_number() over(partition by user_id order by date) as n

    from order_info

    where status = 'completed' and date > '2025-10-15' and product_name in ('C++','Java','Python')

) a

group by user_id

having sum(1) >= 2


 

Q6

牛客的课程订单分析(六)


有很多同学在牛客购买课程来学习,购买会产生订单存到数据库里。

有一个订单信息表(order_info),简况如下:

第1行表示user_id为557336的用户在2025-10-10的时候使用了client_id为1的客户端下了C++课程的非拼团(is_group_buy为No)订单,但是状态为没有购买成功。

第2行表示user_id为230173543的用户在2025-10-12的时候使用了client_id为2的客户端下了Python课程的非拼团(is_group_buy为No)订单,状态为购买成功。

。。。

最后1行表示user_id为557336的用户在2025-10-25的时候使用了下了C++课程的拼团(is_group_buy为Yes)订单,拼团不统计客户端,所以client_id所以为0,状态为购买成功。


有一个客户端表(client),简况如下:

请你写出一个sql语句查询在2025-10-15以后,同一个用户下单2个以及2个以上状态为购买成功的C++课程或Java课程或Python课程的订单id,是否拼团以及客户端名字信息,最后一列如果是非拼团订单,则显示对应客户端名字,如果是拼团订单,则显示NULL,并且按照order_info的id升序排序

06

牛客的课程订单分析(六)

自己思考几分钟,在看下我的思路:

点击空白处查看答案

1. 先找购买成功对应课程的信息以及数量

2. 关联client表,找到对应name由于团购显示Null,即用left关联

3. 要求下单2个以及以上添加条件过滤


select a.id,is_group_buy,name

from

(select *,count(*)over(partition by user_id) as count_num

from order_info

where product_name in ('C++','Java','Python')

and status='completed'

and date >'2025-10-15') a

left join client b

on a.client_id = b.id

where a.count_num >=2

order by id asc;


 

Q7

牛客的课程订单分析(七)


有很多同学在牛客购买课程来学习,购买会产生订单存到数据库里。

有一个订单信息表(order_info),简况如下:


第1行表示user_id为557336的用户在2025-10-10的时候使用了client_id为1的客户端下了C++课程的非拼团(is_group_buy为No)订单,但是状态为没有购买成功。

第2行表示user_id为230173543的用户在2025-10-12的时候使用了client_id为2的客户端下了Python课程的非拼团(is_group_buy为No)订单,状态为购买成功。

。。。

最后1行表示user_id为557336的用户在2025-10-25的时候使用了下了C++课程的拼团(is_group_buy为Yes)订单,拼团不统计客户端,所以client_id所以为0,状态为购买成功。


有一个客户端表(client),简况如下:


请你写出一个sql语句查询在2025-10-15以后,同一个用户下单2个以及2个以上状态为购买成功的C++课程或Java课程或Python课程的来源信息,第一列是显示的是客户端名字,如果是拼团订单则显示GroupBuy,第二列显示这个客户端(或者是拼团订单)有多少订单,最后结果按照第一列(source)升序排序

07

牛客的课程订单分析(七)

自己思考几分钟,在看下我的思路:

点击空白处查看答案

1. 依照前面题的思路,很容易写出来

2. 唯一变化的地方就是增加了client表中name进行分组



select

case when A.is_group_buy = "Yes" then "GroupBuy" else B.name end as source,

count(*) as cnt

from

(

    select *

    from

    (

        select is_group_buy, client_id,

        count(*) over(partition by user_id) as number

        from

        order_info

        where product_name in ("C++", "Java", "Python")

        and status = 'completed'

        and date > '2025-10-15'

    ) as t

    where t.number >= 2

) as A

left join

client B

on A.client_id = B.id

group by case when A.is_group_buy = "Yes" then "GroupBuy" else B.name end

order by source;



 

Q8

实习广场投递简历分析(一)


在牛客实习广场有很多公司开放职位给同学们投递,同学投递完就会把简历信息存到数据库里。

现在有简历信息表(resume_info),部分信息简况如下


第1行表示,在2025年1月2号,C++岗位收到了53封简历

。。。

最后1行表示,在2026年1月4号,Java岗位收到了230封简历


请你写出SQL语句查询在2025年内投递简历的岗位和数量,并且按数量降序排序

08

实习广场投递简历分析(一)

自己思考几分钟,在看下我的思路:

点击空白处查看答案

1. 利用函数year找到对应的年份

2. 统计岗位的数量,排序


SELECT job,SUM(num) AS cnt

FROM resume_info

WHERE year(date) = 2025

GROUP by job

ORDER BY cnt DESC;


 

Q9

实习广场投递简历分析(二)


在牛客实习广场有很多公司开放职位给同学们投递,同学投递完就会把简历信息存到数据库里。

现在有简历信息表(resume_info),部分信息简况如下


第1行表示,在2025年1月2号,C++岗位收到了53封简历

。。。

最后1行表示,在2026年1月4号,Java岗位收到了230封简历


请你写出SQL语句查询在2025年内投递简历的每个岗位,每一个月内收到简历的数量,并且按先按月份降序排序,再按简历数目降序排序

09

实习广场投递简历分析(二)

自己思考几分钟,在看下我的思路:

点击空白处查看答案

1. 利用date_format(date,’%Y-%m’)找到月份

2. 分组求和,排序


SELECT job,DATE_FORMAT(date,'%Y-%m') as mon,sum(num) as cnt

FROM resume_info ri

where DATE_FORMAT(date,'%Y')  = '2025'

group by job,mon

order by mon desc,cnt desc


 

Q10

实习广场投递简历分析(三)


在牛客实习广场有很多公司开放职位给同学们投递,同学投递完就会把简历信息存到数据库里。

现在有简历信息表(resume_info),部分信息简况如下


第1行表示,在2025年1月2号,C++岗位收到了53封简历

。。。

最后1行表示,在2026年1月4号,Java岗位收到了230封简历


请你写出SQL语句查询在2025年投递简历的每个岗位,每一个月内收到简历的数目,和对应的2026年的同一个月同岗位,收到简历的数目,最后的结果先按first_year_mon月份降序,再按job降序排序显示

10

实习广场投递简历分析(三)

自己思考几分钟,在看下我的思路:

点击空白处查看答案

1. 行转列首先想到关联,同时两个年维度,需要关联两次

2. 分别找到2025年和2026年的数据每个月份的数据

3. 关联起来,同时月份对应相等


select s1.job,date_format(s1.date,'%Y-%m') as first_year_mon,s1.cnt first_year_cnt,

date_format(s2.date,'%Y-%m') second_year_mon,s2.cnt as second_year_cnt

from (select job,date,sum(num) cnt

    from resume_info

    where year(date) ='2025'

    group by job,month(date)) s1

join (select job,date,sum(num) cnt

     from resume_info

     where year(date) = '2026'

      group by job,month(date)) s2

on s1.job = s2.job

and month(s1.date) = month(s2.date)

order by first_year_mon desc,job desc


 

OS:每天坚持跟山虎做十道题,几天之后你的sql功底就会突飞猛进。sql实战到就结束了。

大家好,我是山虎,喜欢数学,编码,算法,股票,AI。经历过一次失败的创业。东西不要死记硬背,要做到自己真正的理解。年轻人就要折腾,年轻人就要折腾,年轻人就要折腾。原创不易,帮忙转发。

JAVA八股文

随时欢迎与我讨论各种问题

文章转载自Java八股文宝典,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论