首页 > 试题广场 >

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

[编程题]牛客每个人最近的登录日期(四)
  • 热度指数:134587 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
牛客每天有很多人登录,请你统计一下牛客每个日期登录新用户个数,
有一个登录(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 2 2 2020-10-13
5 1 2 2020-10-13
6 3 1 2020-10-14
7 4 1 2020-10-14
8 4 1 2020-10-15
第1行表示user_id为2的用户在2020-10-12使用了客户端id为1的设备登录了牛客网,因为是第1次登录,所以是新用户
。。。
第4行表示user_id为2的用户在2020-10-13使用了客户端id为2的设备登录了牛客网,因为是第2次登录,所以是老用户
。。
最后1行表示user_id为4的用户在2020-10-15使用了客户端id为1的设备登录了牛客网,因为是第2次登录,所以是老用户


请你写出一个sql语句查询每个日期登录新用户个数,并且查询结果按照日期升序排序,上面的例子查询结果如下:

date
new
2020-10-12
3
2020-10-13
0
2020-10-14
1
2020-10-15
0
查询结果表明:
2020-10-12,有3个新用户(user_id为2,3,1)登录
2020-10-13,没有新用户登录
2020-10-14,有1个新用户(user_id为4)登录
2020-10-15,没有新用户登录

示例1

输入

drop table if exists login;
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`));

INSERT INTO login VALUES
(1,2,1,'2020-10-12'),
(2,3,2,'2020-10-12'),
(3,1,2,'2020-10-12'),
(4,2,2,'2020-10-13'),
(5,1,2,'2020-10-13'),
(6,3,1,'2020-10-14'),
(7,4,1,'2020-10-14'),
(8,4,1,'2020-10-15');

输出

2020-10-12|3
2020-10-13|0
2020-10-14|1
2020-10-15|0
with dateList as (
    select distinct
        login.date
    from login
),

newUserLogin as (
    select 
    firstDate as "date", 
    count(*) as new
from(select distinct
    user_id,
    min(date) as firstDate
from login 
group by user_id) as temp 
group by firstDate

)

select
    dateList.date,
    coalesce(new,0) as new
from dateList left join newUserLogin on dateList.date = newUserLogin.date

发表于 2025-12-21 15:10:09 回复(0)
select
    date,
    count(*) as new
from
    (
        select
            user_id,
            min(date) as date
        from
            login
        group by
            user_id
    ) as t
group by
    date

这样只能实现给出用户登录过的日期的统计无法包含新用户数为0的日期
发表于 2025-11-29 14:08:45 回复(0)
select date,
ifnull(count(distinct case when date = m_date then user_id end), 0) new
from(
select *, min(date) over(partition by user_id) m_date
from login
)tb1
group by date
order by date;
发表于 2025-11-12 21:26:09 回复(1)
with t1 as(
    select user_id,date,dense_rank()over(partition by user_id order by date)r
from login )

select date,count(distinct user_id)new
from t1
where r=1
group by date
order by date
请教一个各位朋友,我这个答案哪里不对啊?
发表于 2025-11-11 17:36:46 回复(1)
with t1 as (select distinct user_id,date from login),t2 as 
(select user_id,date,min(date) over(partition by user_id) as min_num
from t1)
select date,sum(if(date=min_num,1,0)) as new
from t2
group by 1
order by 1

发表于 2025-10-15 18:26:56 回复(0)
select distinct l.date, (case when t2.new is null then 0 else t2.new end) new
from login l
left join (
    select new_cnt as date, count(*) as new
    from (
        select min(date) as new_cnt
        from login
        group by user_id
    ) t1
    group by date
) t2
on l.date = t2.date
思路: 1. 子查询t1:找到每个用户第一次登录的日期(min(date)),按user_id分组。
2. 子查询t2:将t1的结果按日期分组,统计每个日期的新用户数量。
3. 外层查询:从login表获取所有日期(distinct l.date),然后左连接t2,这样即使某天没有新用户,也会显示0。
发表于 2025-07-25 08:27:51 回复(0)
with
    p1 as (
        select
            min(date) as first_date,
            user_id
        from
            login
        group by
            user_id
    ),
    p2 as (
        select
            p1.first_date,
            count(p1.first_date) as new
        from
            p1
        group by
            p1.first_date
    ),
    all_date as (
        select distinct
            date
        from
            login
    )
select
    all_date.date,
    if( p2.new, p2.new, 0 ) as 'new'
from
    all_date left join p2 on all_date.date = p2.first_date;
发表于 2025-06-24 18:10:26 回复(0)
--感觉窗口函数可能更直观点 但我用的这个
select date, sum(case when l.date = (select min(date) from login where user_id = l.user_id group by user_id) then 1 else 0 end) as new
from login l
group by date
order by date;
发表于 2025-05-14 19:26:26 回复(0)
select
    date,
    sum(if(date = m,1,0)) new
from
(
    select
        date,
        min(date) over(partition by user_id) m
    from (select date,user_id from login group by date,user_id) t1
) t2
group by
    date

发表于 2025-04-24 23:51:18 回复(0)
感觉我这个挺简单的
with a as (select *,rank() over (partition by user_id order by date ) as rk from login)
select date,sum(if(rk=1,1,0)) from a group by date           
发表于 2025-03-26 13:46:03 回复(0)
错误写法一:不显示新用户为0的用户
select date, count(*)
from login
where (user_id, date) in (
    select user_id, min(date)
    from login
    group by user_id
)
group by date
order by date
错误写法二:having要跟聚合字段
select date, count(*)
from login
group by date
having (user_id, date) in (
    select user_id, min(date)
    from login
    group by user_id
)



发表于 2025-03-15 13:53:05 回复(0)
select
date,
sum(if(r=1,1,0))
from    
    (select
    *,
    rank()over(partition by user_id order by date asc) r
    from
    login) u
group by date

发表于 2025-03-12 11:40:13 回复(0)
SELECT date,count(re.rk=1&nbs***bsp;null) new
FROM
(
SELECT user_id,date,row_number()over(partition by user_id order by date) rk
from login
)re
group by date
order by date

发表于 2025-02-07 20:54:03 回复(0)
select distinct l.date
,case when zi2.new1!=0 then zi2.new1 else 0 end new
from login l left join
(
select zi.md md2
,count(zi.md) new1
from
(
select min(date) md
from login
group by user_id
) zi
group by zi.md
) zi2
on l.date=zi2.md2
order by l.date
发表于 2025-02-06 17:22:08 回复(0)
一开始的想法如下,把最早的日期分组出来,然后计数即可,但是发现这种写***漏掉没有新人登录的日期,想着用日期分组之后左连接过去,又卡在了null值的问题上,最后靠ai提醒还有coalesce这种神奇的函数。最后解决问题,不过这个方法应该不算什么特别好的方法,虽然想法很直接。
select da, count(da) as new
from
    (select user_id, min(date) as da
    from login
    group by user_id
    ) as a
group by da
order by da
发表于 2025-02-06 00:29:17 回复(0)
with t1 as (
    select
      user_id,
      `date`
    from login
    group by user_id, `date`
),
t2 as (
    select
      user_id,
      min(`date`) first_login
    from t1
    group by user_id
),
t3 as (
    select
      `date`
    from t1
    group by `date`
),
t4 as (
    select
      t3.`date`,
      count(t2.user_id) as new
    from t3
    left join t2 
      on t3.`date` = t2.first_login
    group by t3.`date`
)
select * from t4;
发表于 2025-01-21 20:16:46 回复(0)
select date,count(*) new
from login
where (user_id,date) in( select user_id, min(date) 
from login 
group by user_id)
group by date
这种只能统计不为0的
发表于 2025-01-06 14:09:09 回复(0)
with t1 as(select
user_id,date,
rank() over(partition by user_id order by date) r
from login)

select t2.date,
length(h)-length(replace(h,'1','')) as new
from (select t1.date,group_concat(r) h
from t1
group by t1.date) t2
发表于 2024-12-02 13:51:20 回复(0)
select date,sum(case when r_date =1 then 1 else 0 end) as new
from (select user_id,rank()over(partition by user_id order by date) as r_date,date
    from login) as a
group by date
发表于 2024-11-11 20:59:42 回复(0)