首页 > 试题广场 >

牛客每个人最近的登录日期(六)

[编程题]牛客每个人最近的登录日期(六)
  • 热度指数:95604 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
牛客每天有很多人登录,请你统计一下牛客每个用户刷题情况,包括: 用户的名字,以及截止到某天,累计总共通过了多少题。 不存在没有登录却刷题的情况,但存在登录了没刷题的情况,不会存在刷题表里面,会存在提交代码没有通过的情况并记录在刷题表里,通过数目是0。
有登录(login)记录表,简况如下:
id
user_id client_id
date
1 2 1 2020-10-12
2 3 2 2020-10-12
3 1 2 2020-10-12
4 1 3 2020-10-13
5 3 2 2020-10-13
第1行表示user_id为2的用户在2020-10-12使用了客户端id为1的设备登录了牛客网
......
第5行表示user_id为3的用户在2020-10-13使用了客户端id为2的设备登录了牛客网


有刷题(passing_number)表,简况如下:
id
user_id number
date
1 2 4 2020-10-12
2 3 1 2020-10-12
3 1 0 2020-10-13
4 3 2 2020-10-13
第1行表示user_id为2的用户在2020-10-12通过了4个题目。
......
第3行表示user_id为1的用户在2020-10-13提交了代码但是没有通过任何题目。
第4行表示user_id为3的用户在2020-10-13通过了2个题目


有用户(user)表,注:这里id字段对应user_id,简况如下:
id name
1 tm
2 fh
3 wangchao
请你写出一个sql语句查询刷题信息,包括: 用户的名字,以及截止到某天,累计总共通过了多少题,并且查询结果先按照日期升序排序,再按照姓名升序排序,有登录却没有刷题的哪一天的数据不需要输出,上面的例子查询结果如下:
u_n date ps_num
fh 2020-10-12 4
wangchao
2020-10-12
1
tm 2020-10-13
0
wangchao 2020-10-13
3

查询结果表明:
fh在2020-10-12为止,总共通过了4道题,输出为4
wangchao在2020-10-12为止总共通过了1道题,总计为1
tm在2020-10-12为止只登陆了没有刷题,故没有显示出来
tm在2020-10-13为止刷了题,但是却没有通过任何题目,总计为0
wangchao在2020-10-13通过2道,但是加上前面2020-10-12通过1道,故在2020-10-13为止总共通过了3道题,总计为3

示例1

输入

drop table if exists login;
drop table if exists passing_number;
drop table if exists user;
drop table if exists client;
CREATE TABLE `login` (
`id` int(4) NOT NULL,
`user_id` int(4) NOT NULL,
`client_id` int(4) NOT NULL,
`date` date NOT NULL,
PRIMARY KEY (`id`));

CREATE TABLE `passing_number` (
`id` int(4) NOT NULL,
`user_id` int(4) NOT NULL,
`number` int(4) NOT NULL,
`date` date NOT NULL,
PRIMARY KEY (`id`));

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


INSERT INTO login VALUES
(1,2,1,'2020-10-12'),
(2,3,2,'2020-10-12'),
(3,1,2,'2020-10-12'),
(4,1,3,'2020-10-13'),
(5,3,2,'2020-10-13');

INSERT INTO passing_number VALUES
(1,2,4,'2020-10-12'),
(2,3,1,'2020-10-12'),
(3,1,0,'2020-10-13'),
(4,3,2,'2020-10-13');

INSERT INTO user VALUES
(1,'tm'),
(2,'fh'),
(3,'wangchao');

输出

fh|2020-10-12|4
wangchao|2020-10-12|1
tm|2020-10-13|0
wangchao|2020-10-13|3
select
    name,
    a.date,
    s
from
    (
        select
            user_id,
            date,
            sum(number) over (
                partition by
                    user_id
                order by
                    date
            ) s
        from
            passing_number
    ) a
    left join user on a.user_id = user.id
order by
    a.date asc,
    name asc

发表于 2026-01-13 01:34:20 回复(0)
# 统计一下牛客每个用户刷题情况,包括: 用户的名字,以及截止到某天,累计总共通过了多少题。
with allInformation as(
    select 
        login.user_id,
        name,
        login.date,
        number
    from login left join passing_number on login.user_id = passing_number.user_id and login.date = passing_number.date
    left join user on login.user_id = user.id

)
select
    *
from(select 
    name as u_n,
    allInformation.date,
    sum(number) over(partition by name order by date)as ps_num
from allInformation) as temp
where ps_num is not null
order by date,u_n

发表于 2025-12-26 15:02:23 回复(0)
with t1 as (
select x.user_id,x.date,number
from login x
join passing_number y
on x.user_id=y.user_id and x.date=y.date
)
select name as u_n,date,sum(number) over(partition by name order by date) as ps_num
from t1 
join user x 
on t1.user_id=x.id
order by 2,1

发表于 2025-10-15 18:43:45 回复(0)
SELECT name u_n, date, SUM(number)OVER(PARTITION BY user_id ORDER BY date) ps_num
FROM passing_number pn
LEFT JOIN user u ON pn.user_id = u.id
ORDER BY date, u_n

发表于 2025-08-20 18:04:32 回复(0)
select 
    u.name as u_n,
    l.date as date,
    sum(p.number) over(partition by u.name order by date) as ps_num
from login l
join passing_number p
on l.user_id = p.user_id and l.date = p.date
join user u 
on l.user_id = u.id
order by date,u_n;
发表于 2025-07-17 16:40:22 回复(0)
select u.name u_n,l.date date,sum(pn.number) ps_num
from login l
left join passing_number pn on l.user_id = pn.user_id
left join user u on u.id = pn.user_id
group by u.name,l.date
默默问一句,我这哪错了?
发表于 2025-06-06 11:00:16 回复(0)
select
    temp1.name,
    temp1.date,
    sum(p.number) over (
        partition by
            temp1.name
        order by
            temp1.date
    )
from
    (
        select
            l.user_id user_id,
            l.date date,
            u.name name
        from
            login l
            inner join user u on l.user_id = u.id
    ) temp1
    inner join passing_number p on temp1.user_id = p.user_id
where
    temp1.date = p.date
order by
    temp1.date

发表于 2025-01-08 18:00:09 回复(0)

不使用窗口函数的写法

select t2.name, t1.date, t1.total_num
from (
    -- 用于计算刷题累计数量
    select t1.date, t1.user_id, sum(t2.number) as total_num
    from login t1 
    left join passing_number t2 on t1.user_id = t2.user_id and t1.date >= t2.date
    -- 此处用于过滤登录单位刷题的信息
    where t2.number is not null
    group by t1.date, t1.user_id
) t1 left join user t2 on t1.user_id = t2.id
order by t1.date asc, t2.name asc

使用窗口函数会更简单一些

select t2.name, t1.date, t1.num
from (
    select date, user_id
    -- 窗口函数直接聚合累计计算
    , sum(number) over(partition by user_id order by date) as num
    from passing_number
) t1 left join user t2 on t1.user_id = t2.id
order by t1.date asc, t2.name asc
发表于 2024-08-13 11:36:18 回复(0)
窗口函数求和
select
    t2.name as u_n,
    t1.date,
    sum(t3.number) over(partition by t2.name ORDER BY t1.date) as ps_num
    -- 通过窗口函数 对每个用户在每个日期的刷题记录进行累计
from  
    login t1
    join user t2  on t1.user_id =t2.id  -- 为每个登录记录匹配用户昵称,
    join passing_number  t3 on (t1.user_id =t3.user_id and t1.date=t3.date )  
    -- 获得每次登陆的刷题数量;同时通过inner join 也能消除掉有登录但未刷题的记录
order by
    `date` asc,u_n asc


发表于 2024-07-09 19:32:19 回复(0)
select
    u.name u_n,
    pn.date date,
    sum(number) over (partition by pn.user_id order by pn.date) ps_num
from passing_number pn join user u 
on pn.user_id=u.id
order by date,u_n
发表于 2024-06-11 22:21:39 回复(0)
select
    t.name u_n,
    t.date,
    sum(t.number) over (
        partition by
            t.name
        order by
            t.date
    ) ps_num
from
    (
        select
            a.user_id,
            b.name,
            a.date,
            a.number
        from
            passing_number a
            left join user b on a.user_id = b.id
    ) t
order by
    t.date asc

发表于 2024-05-24 10:39:43 回复(0)
select u.name as u_n,p.date as date,sum(p.number) over(partition by user_id order by date) as ps_num
from passing_number p
left join user u on p.user_id = u.id
order by date asc,u_n asc

发表于 2024-04-25 09:59:37 回复(0)
借鉴了题解里开窗函数的用法,具体代码如下:
SELECT
    u.name AS u_n,
    p.date,
    p.ps_num
FROM(
    SELECT
        user_id,
        date,
        sum(number)OVER(PARTITION BY user_id ORDER BY date) AS ps_num
    FROM passing_number
    GROUP BY user_id, date, number
) AS p
LEFT JOIN user u 
    ON u.id = p.user_id
WHERE p.user_id IN(
    SELECT user_id
    FROM login
    WHERE date = p.date
)
ORDER BY p.date, u_n;


编辑于 2024-04-15 10:20:52 回复(0)
select b.name u_n,a.date,sum(a.number) over(partition by a.user_id order by a.date) ps_num
from passing_number a, user b 
where a.user_id=b.id 
order by a.date,u_n

发表于 2023-12-29 10:54:05 回复(0)
select name u_n
,date
,sum(number)over(partition by user_id order by date) ps_num
from passing_number a
inner join user b
on a.user_id=b.id
order by date,name
-------------------------------------------------------------------------------------
select name u_n
,a.date
,sum(c.number)
from passing_number a
inner join user b
on a.user_id=b.id
left join passing_number c
on  a.user_id=c.user_id and a.date>=c.date
group by u_n,a.date
order by date,name

编辑于 2023-12-01 16:06:57 回复(0)
# 请你写出一个sql语句查询刷题信息,包括: 用户的名字,以及截止到某天,累计总共通过了多少题,
# 并且查询结果先按照日期升序排序,再按照姓名升序排序,有登录却没有刷题的哪一天的数据不需要输出

# 注意本题考查,时间累积;

with dwd_data as (
select 
t2.name,
t1.date,
sum(t1.number)over(partition by user_id order by t1.date asc ) as sum_number
from passing_number t1 left join user t2
on t1.user_id = t2.id 
) 

select 
name,
date,
sum_number
from dwd_data 
order by 2,1
;

发表于 2023-09-22 14:27:02 回复(0)
不需要用到login表
select name as u_n,date,ps_num from user
inner join
(select user_id,date,
sum(number)over(partition by user_id order by date) as ps_num
from passing_number
order by user_id,date) as a
on user.id = a.user_id
order by date,u_n

发表于 2023-05-06 17:03:09 回复(0)
前缀和例题
# 有登录却没有刷题的哪一天的数据不需要输出
# login这张表没有用到

with total_info as (
    select pn.user_id,pn.number,pn.date,
    user.name as u_n
    from passing_number pn
    left join user 
    on pn.user_id=user.id
)
# 之后前缀和就行
select u_n,date,sum(number) over(partition by user_id order by date asc)as ps_num 
from total_info
order by date asc,u_n asc



发表于 2023-03-23 21:45:59 回复(0)
select u.name,p.date
,sum(number) over (partition by u.name order by p.date) ps_num
from passing_number p left join user u
on p.user_id = u.id
order by p.date,name;

发表于 2023-01-15 23:54:24 回复(0)

问题信息

SQL
难度:
113条回答 3944浏览

热门推荐

通过挑战的用户

查看代码
牛客每个人最近的登录日期(六)