首页 > 试题广场 >

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

[编程题]牛客的课程订单分析(四)
  • 热度指数:66242 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解

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

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

id user_id product_name
status
client_id
date
1 557336
C++
no_completed
1 2025-10-10
2 230173543
Python
completed
2 2025-10-12
3 57 JS
completed
3 2025-10-23
4 57 C++
completed
3 2025-10-23
5 557336
Java
completed
1 2025-10-23
6 57 Java
completed
1 2025-10-24
7 557336
C++
completed
1 2025-10-25
8 557336
Python
completed
1 2025-10-25

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

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

。。。

最后1行表示user_id557336的用户在2025-10-25的时候使用了client_id1的客户端下了Python课程的订单,状态为购买成功。

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

user_id first_buy_date cnt
57 2025-10-23 2
557336 2025-10-23 3

解析:

id为46的订单满足以上条件,输出57id为4的订单为第一次购买成功,输出first_buy_date为2025-10-23,总共成功购买了2;

id为578的订单满足以上条件,输出557336id为5的订单为第一次购买成功,输出first_buy_date为2025-10-23,总共成功购买了3;

示例1

输入

drop table if exists order_info;
CREATE TABLE order_info (
id int(4) NOT NULL,
user_id int(11) NOT NULL,
product_name varchar(256) NOT NULL,
status varchar(32) NOT NULL,
client_id int(4) NOT NULL,
date date NOT NULL,
PRIMARY KEY (id));

INSERT INTO order_info VALUES
(1,557336,'C++','no_completed',1,'2025-10-10'),
(2,230173543,'Python','completed',2,'2025-10-12'),
(3,57,'JS','completed',3,'2025-10-23'),
(4,57,'C++','completed',3,'2025-10-23'),
(5,557336,'Java','completed',1,'2025-10-23'),
(6,57,'Java','completed',1,'2025-10-24'),
(7,557336,'C++','completed',1,'2025-10-25'),
(8,557336,'Python','completed',1,'2025-10-25');

输出

57|2025-10-23|2
557336|2025-10-23|3
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('C++','Java','Python')
group by user_id having count(user_id)>1) and date>'2025-10-15' and status='completed' and product_name in('C++','Java','Python') order by id
可以将以上查询的结果当成一个新的表,那么这样思考就简单很多了,把这个新的表,按照user_id聚合,并且取出这种情况的最小购买时间,以及count(user_id),就能得到正确结果,如下:
select user_id,min(date) as first_buy_date,count(user_id) as cnt from

(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('C++','Java','Python')
group by user_id having count(user_id)>1) and date>'2025-10-15' and status='completed' and product_name in('C++','Java','Python') order by id) table_a

group by user_id order by user_id;

其实这个题目订单(二)和订单(三)筛选的东西,聚合之后是一样的,所以根据订单(二)的写法,加聚合更简单,:
select user_id,min(date) first_buy_date,count(user_id) cnt
from order_info
where date > '2025-10-15'
and product_name in ('C++','Java','Python')
and status = 'completed'
group by user_id
having count(user_id) > 1
order by user_id



编辑于 2021-03-03 10:38:20 回复(2)
!!!group子句可以搭配多个聚合函数一起使用,比如本例中的count和min
根据Date、Status、Product_name筛除一些行
根据user_id分组统计cnt
min(date)筛选最靠前的日期
having子句筛选满足大于2的行
排序
发表于 2021-08-03 18:34:10 回复(0)
普通的分组聚合即可,看到题目较难差点就要用各种窗口函数解决了
select user_id,min(date) first_buy_date,count(1) 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)>=2
order by user_id
发表于 2022-01-25 09:45:33 回复(0)
select user_id
,min(date) first_buy_date
,count(id) cnt
from order_info
where status = 'completed'
and date > '2025-10-15'
and product_name in ('C++','Java','Python')
group by user_id
having count(id) > 1
order by user_id asc;

发表于 2021-11-07 20:29:24 回复(0)
SELECT
	t.user_id,
	Min( t.date ) AS first_buy_date,
	COUNT( t.user_id ) AS cnt 
FROM
	(
	SELECT
		ROW_NUMBER() OVER ( PARTITION BY user_id ORDER BY date ASC ) AS t_rank,
		user_id,
		product_name,
		date 
	FROM
		order_info 
	WHERE
		product_name IN ( 'C++', 'Java', 'Python' ) 
		AND date > '2025-10-15' 
		AND STATUS = 'completed' 
	) AS t 
GROUP BY
	t.user_id 
HAVING
	COUNT( t.t_rank ) >= 2 
ORDER BY
	t.user_id ASC

发表于 2021-09-25 22:51:40 回复(0)
SELECT
    *
from(
    SELECT
        user_id,min(date),count(*) as c
    FROM
        order_info
    where
        date > '2025-10-15'
    and
        product_name in ('Java','C++','Python')
    and
        status = 'completed'
    group BY
        user_id) t
where t.c>=2
order BY user_id

发表于 2021-08-01 16:05:25 回复(0)
select user_id,min(date) as first_buy_date,count(user_id) as cnt
from order_info
where date > '2025-10-15' and product_name in ('C++','Java','Python') and
status = 'completed'
Group by user_id
HAVING count(user_id) >=2
order by user_id;
发表于 2021-07-26 16:16:41 回复(0)
差点没想起来用min,还想着又要把生成的新表再内联找最小值……因为觉得太麻烦了多想了会儿才想到min,希望下次再做能一下子想到做法
#获取满足条件的记录
SELECT info.user_id, info.date AS first_buy_date, t1.cnt
FROM order_info AS info
JOIN (
        #获取满足条件的用户id
        SELECT user_id,COUNT(*) AS cnt, MIN(date) AS first_buy_date
        FROM order_info
        WHERE product_name IN ('C++','Java','Python') AND date>'2025-10-15' AND status='completed'
        GROUP BY user_id
        HAVING COUNT(*)>=2
    ) AS t1
ON info.user_id=t1.user_id AND info.date=t1.first_buy_date
WHERE info.product_name IN ('C++','Java','Python') AND info.date>'2025-10-15' 
    AND info.status='completed'
ORDER BY user_id;
    


发表于 2021-06-11 22:35:34 回复(0)
代码如下:
with sub as(select * from order_info
                   where date >'2025-10-15' and status = 'completed' and product_name in('c++','python','java'))
select user_id,min(date),count(status) from sub group by user_id
having count(status) >= 2 order by user_id

发表于 2021-05-23 13:49:04 回复(0)
select user_id, date as first_buy_date, cnt
from (
    select *,
        count(*) over(partition by user_id) as cnt,
        row_number() over(partition by user_id order by date) as rnk
    from order_info
    where date > '2025-10-15'
    and status = 'completed'
    and product_name in('Python','Java','C++')
) a 
where rnk = 1
and cnt >= 2
order by user_id;

发表于 2021-05-23 09:50:03 回复(0)
SELECT user_id,MIN(date) first_buy_date, t_rank cnt FROM  
(
    SELECT *,COUNT(status) OVER(PARTITION BY user_id) t_rank FROM order_info 
    WHERE date > "2025-10-15" 
    AND status = "completed"
    AND product_name in ("C++","Python","Java")
) i
WHERE i.t_rank >= 2
GROUP BY i.user_id
ORDER BY i.user_id;
发表于 2021-05-19 16:45:38 回复(0)
用两个窗口函数分别算出符合条件的首次购买课程的日期以及对应的购买次数:
select 
  user_id, 
  date as first_buy_date,
  cnt
from 
(select 
  user_id,
  date,
  row_number() over(partition by user_id order by date asc) as rn,
  count(*) over(partition by user_id) as cnt
from order_info
where date>'2025-10-15'
  and status='completed'
  and product_name in ('C++','Java','Python')) t 
where t.rn=1 and t.cnt>=2
order by user_id asc 


编辑于 2021-03-16 23:05:51 回复(4)
分析:与之前的"牛客的课程订单分析(二)"唯一区别就是多了两个聚合函数 
min(date) 和 count(user_id),其他都比较常规,参考之前的案例即可 :
select user_id,min(date) first_buy_date,count(user_id) cnt
from order_info
where date > '2025-10-15'
and product_name in ('C++','Java','Python')
and status = 'completed'
group by user_id
having count(user_id) > 1
order by user_id
编辑于 2021-03-05 09:46:54 回复(4)
题目意思好模糊,“所有日期里购买成功的C++课程或Java课程或Python课程的次数cnt”,竟然指的是2025-10-15以后,我吐了
发表于 2022-07-13 15:08:39 回复(2)
我怀疑这题目是来折磨人的。
虽然还是没做出来,但是,抄答案
select user_id, min(date) first_buy_date, count(user_id) cnt
from order_info
where date > '2025-10-15'
and product_name in ('C++', 'Java', 'Python')
and status = 'completed'
group by user_id
having count(user_id) > 1
order by user_id


发表于 2021-04-06 22:25:33 回复(1)
这些题的表述真有问题

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

注意是所有日期成功购买次数,包括2025-10-15之前。可是呢,通过代码只包含2025-10-15之后。

发表于 2022-05-31 15:19:07 回复(0)
这个题目里明明写的是所有日期的数量不是吗?没有限定10.15之后啊。。。
发表于 2023-02-08 14:42:49 回复(0)

有问题啊,不是说要所有日期里购买成功的次数吗?

发表于 2022-08-11 17:25:28 回复(1)
# 思路  这题属于简单级别
1.按照用户分组,求出最小日期(第一次购买日期),再count数量
(算不上较难级别)
select user_id, min(date), count(*)
from order_info
where date > '2025-10-15'
and status = 'completed'
and product_name in ('C++','Python','Java')
group by user_id having count(*)>1
order by user_id


发表于 2022-04-19 16:01:40 回复(0)
我就想知道,如果运营真的提出这种需求,是想分析什么😑😑😑
发表于 2022-02-24 18:59:02 回复(0)