首页 > 试题广场 >

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

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

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

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

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

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

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

。。。

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

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

id name
1 PC
2 Android
3 IOS
4 H5

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

source cnt
GroupBuy 2
IOS 1
PC 1

解析:

id为46的订单满足以上条件,且因为4是通过IOS下单的非拼团订单则记: IOS 1

6是通过PC下单的非拼团订单则记: PC 1;

id为57的订单满足以上条件,且因为57都是拼团订单,则记: GroupBuy 2;

最后按照source升序排序。

示例1

输入

drop table if exists order_info;
drop table if exists client;
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,
is_group_buy varchar(32) NOT NULL,
PRIMARY KEY (id));

CREATE TABLE client(
id int(4) NOT NULL,
name varchar(32) NOT NULL,
PRIMARY KEY (id)
);

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

INSERT INTO client VALUES
(1,'PC'),
(2,'Android'),
(3,'IOS'),
(4,'H5');

输出

GroupBuy|2
IOS|1
PC|1
select distinct source,cnt1
from   
    (select if(is_group_buy ='YES','GroupBuy',name) as source,
      count(*)over(partition by user_id) as cnt,
      count(*)over(partition by c.name) as cnt1
    from order_info oi
    left join client c
    on oi.client_id = c.id
    where product_name in ('C++','Java','Python')
    and status='completed'
    and date >'2025-10-15') f
where cnt >=2

发表于 2025-06-29 20:11:19 回复(0)
select 
    case
        when name is null then 'GroupBuy'
        else name
    end as source,
    COUNT(1) as cnt
from (
        select
            name,client.id as client_id,
            COUNT(*) over(partition by user_id) rk
        from order_info
        left join client ON client.id=order_info.client_id
        where date > '2025-10-15' and product_name in ('C++','Java','Python') and status = 'completed'
) t
where rk >=2
group by source
order by source

发表于 2025-03-02 14:14:52 回复(0)
with t1 as (
    select * from order_info
    where date >= '2025-10-15' and product_name in ('C++', 'Java', 'Python') and status = 'completed'  -- 条件过滤
),
t2 as (
    select user_id from t1
    group by user_id having count(*) >= 2  -- 2次及以上购买
    order by user_id
)

select if(t1.client_id = 0, "GroupBuy", c.name) as source,
       count(*) as cnt
from t1
    inner join t2 on t1.user_id = t2.user_id
    left join client c on t1.client_id = c.id
group by t1.client_id
order by source;

前面的几道同源题,都用到了t1, t2 两个临时表,  最后都再组装一下 🍎
发表于 2025-01-31 10:50:56 回复(0)
with temp1 as
(select 
    case when t2.name is null then 'GroupBuy' else t2.name end as source
from 
(select
    id,
    user_id,
    client_id,
    is_group_buy,
    count(product_name)over(partition by user_id) cnt
from
    order_info
where
    date > '2025-10-15'
    and product_name in ('C++', 'Python', 'Java')
    and status = 'completed') t1
left join client t2 on t1.client_id = t2.id
where t1.cnt >= 2)

select distinct *,count(source) over(partition by source) from temp1 order by source;

发表于 2025-01-09 16:40:15 回复(0)
coalesce(name, 'GroupBuy')替换会方便点,虽然不一定泛用
发表于 2024-12-03 13:17:38 回复(0)
with source_cnt as (
    select c.name,
    count(*)over(partition by o.client_id) client_cnt,
    count(*)over(partition by o.user_id) user_cnt
    from order_info o left join client c
    on o.client_id = c.id
    where product_name in ('C++','Java','Python')
    and status = 'completed'
    and date > '2025-10-15'
)

select distinct ifnull(name,'GroupBuy') as source, client_cnt as cnt
from source_cnt
where user_cnt >= 2
order by source

发表于 2024-11-10 10:47:07 回复(0)
select 
    (case when c.name is null then "GroupBuy" else c.name end) source,
    count(*) cnt
from 
    order_info o
left join 
    client c
    on o.client_id = c.id
where 
    user_id in (
                    #符合条件的用户
                    select
                        user_id
                    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
                )
    and date > "2025-10-15"
    and status = "completed"
    and product_name in ("C++", "Python", "Java")
group by c.name
order by source 

发表于 2024-10-23 15:53:06 回复(0)
with t0 as
(select
user_id

from order_info

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

group by user_id

having count(id)>1)

select

case when name is not null then name else 'GroupBuy' end as source,
count(t1.id)

from 
order_info as t1 left join 
client as t2 
on t1.client_id=t2.id

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

group by source
order by 1



发表于 2024-09-20 13:58:06 回复(0)
select distinct
    source,
    rk as cnt
from
    (
        select
            (
                case
                    when o.client_id = 0 then 'GroupBuy'
                    else c.name
                end
            ) as source,
            count(*) over (
                partition by
                    c.name
            ) as rk,
            count(*) over (
                partition by
                    o.user_id
            ) as rk1
        from
            order_info o
            left join client c on o.client_id = c.id
        where
            status = 'completed'
            and date > '2025-10-15'
            and product_name in ('C++', 'Java', 'Python')
    ) a
where
    rk1 >= 2
order by
    source

发表于 2024-09-18 14:54:42 回复(0)

找到目标数据后,然后做if判断和group by 就好了

select if(t1.is_group_buy = 'Yes', 'GroupBuy', t2.name) as client_name, count(t1.id) as cnt
from (
    select *
    from order_info 
    where 
    product_name in ('C++', 'Java', 'Python')
    and date >= '2025-10-15'
    and status = 'completed'
    and user_id in (
        --  符合条件的user_id
        select user_id
        from order_info 
        where 
        product_name in ('C++', 'Java', 'Python')
        and date >= '2025-10-15'
        and status = 'completed'
        group by user_id
        having count(id) >= 2
    )
) t1 left join client t2 on t1.client_id = t2.id
group by if(t1.is_group_buy = 'Yes', 'GroupBuy', t2.name)
order by if(t1.is_group_buy = 'Yes', 'GroupBuy', t2.name) asc
发表于 2024-08-14 13:54:50 回复(0)
select ifnull(t2.name, 'GroupBuy') as source,
count(t1.user_id) as cnt
from order_info as t1
left join client as t2
on t1.client_id=t2.id
where t1.user_id in
(
    select user_id from order_info
    where datediff(date, '2025-10-15')>0
    and product_name in ('C++', 'Java', 'Python')
    and status='completed'
    group by user_id
    having count(user_id)>1
)
and datediff(t1.date, '2025-10-15')>0
and t1.product_name in ('C++', 'Java', 'Python')
and t1.status='completed'
group by source
order by source;

发表于 2024-07-28 18:14:27 回复(0)
有了前面几题的基础,这题就容易很多了。采用先整体后局部的方法,先看题目整体给出的数据表和表数据。order_info,client 两个表,那肯定涉及多表操作:左连接?右连接?多表连接?再看题目要求。
题目要求可以分两部分:
1:查询在2025-10-15以后,同一个用户下单2个以及2个以上状态为购买成功的C++课程或Java课程或Python课程的来源信息。前面题目已经写过很多次了
select *
from
(
    select *,count(id) over(partition by user_id) as number
    from order_info
    where datediff(date,"2025-10-15")>0
      and status ="completed"
      and product_name in ("C++","Java","Python")  
) t1   
where t1.number >1 


2:查询结果有两列:第一列是显示的是客户端名字,如果是拼团订单则显示GroupBuy。但client表name字段并无GroupBuy值,很明显需要我们赋值处理:if  或者case ...when...   第二列显示这个客户端(或者是拼团订单)有多少订单,按客户端分组统计嘛,group by 关键字。最后结果按照第一列(source)升序排序,order by source。

在理解题目后,再观察表数据:order_info表中的client_id 和is_group_buy的值是有对应关联的。当is_group_buy是YES时,client_id是0。

select
    if (c.name is NULL, 'GroupBuy', c.name) source,
    count(*) cnt
from
    (
        select
            *,
            count(*) over (
                partition by
                    user_id
            ) as ocnt
        from
            order_info
        where
            date > '2025-10-15'
            and status = 'completed'
            and product_name in ('C++', 'Java', 'Python')
    ) o
    left join client c on o.client_id = c.id
where
    ocnt > 1
group by
    source
order by
    source;






发表于 2024-07-23 15:13:56 回复(0)
with t1 as (
    select o.id,
    case when o.is_group_buy = 'Yes' then 'GroupBuy' else c.name end as source
    from order_info o
    left join client c on o.client_id = c.id
    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) >=2
    ) and date > '2025-10-15' and status ='completed' and product_name in ('C++', 'Java', 'Python')
)
select t1.source, count(t1.id)
from t1
group by t1.source
order by t1.source

发表于 2024-07-22 16:11:17 回复(0)
select
    if(t.client_id=0,'GroupBuy',c.name) source,
    count(t.id) cnt
from (
    select
        id,
        client_id
    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(id)>=2
    ) and date>'2025-10-15' and status='completed' and product_name in ('C++','Java','Python')
) t left join client c
on t.client_id=c.id
group by t.client_id
order by source
发表于 2024-06-11 22:57:36 回复(0)

select distinct c.name, count(*) over(partition by c.name) cnt
from
    (select a.id,
    (case when b.name is null then 'GroupBuy' else b.name end) name,
    count(*) over(partition by user_id) n
    from order_info a left join client b on a.client_id = b.id
    where a.status = 'completed' and a.date > '2025-10-15' and a.product_name in('C++', 'Java', 'Python')) c
where c.n >= 2
发表于 2024-06-06 17:30:51 回复(0)
SELECT 
    source,
    count(*) AS cnt
FROM(
    SELECT 
        o.user_id,
        CASE 
            WHEN o.client_id = 0 THEN 'GroupBuy' 
            ELSE c.name
        END AS source
    FROM order_info o
    LEFT JOIN client c 
        ON o.client_id = c.id
    WHERE o.date > '2025-10-15'
        AND o.product_name IN ('C++', 'Python', 'Java')
        AND o.status = 'completed'
        AND o.user_id IN (
            SELECT user_id
            FROM order_info
            WHERE date > '2025-10-15'
                AND product_name IN ('C++', 'Python', 'Java')
                AND status = 'completed'
            GROUP BY user_id
            HAVING count(*) >= 2
        )
) AS o2
GROUP BY source
ORDER BY source;

发表于 2024-04-19 10:18:40 回复(0)
with t as (select a.id,a.is_group_buy,b.name,a.client_id,count(a.id)over(partition by user_id) as num from order_info a left join client b on a.client_id=b.id where date >'2025-10-15' and status='completed' and product_name in ('C++','Java','Python'))
select distinct if(is_group_buy='No',name,'GroupBuy') as source,count(id)over(partition by client_id) cnt from t where num>=2 order by source;
发表于 2024-02-20 21:21:26 回复(0)