首页 > 试题广场 >

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

[编程题]牛客每个人最近的登录日期(二)
  • 热度指数:178578 时间限制: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 2 2 2020-10-13
4 3 2 2020-10-13
第1行表示user_id为2的用户在2020-10-12使用了客户端id为1的设备登录了牛客网
。。。
第4行表示user_id为3的用户在2020-10-13使用了客户端id为2的设备登录了牛客网

还有一个用户(user)表,简况如下:
id name
1 tm
2 fh
3 wangchao

还有一个客户端(client)表,简况如下:
id name
1 pc
2 ios
3 anroid
4 h5
请你写出一个sql语句查询每个用户最近一天登录的日子,用户的名字,以及用户用的设备的名字,并且查询结果按照user的name升序排序,上面的例子查询结果如下:
u_n c_n date
fh ios 2020-10-13
wangchao ios 2020-10-13
查询结果表明:
fh最近的登录日期在2020-10-13,而且是使用ios登录的
wangchao最近的登录日期也是2020-10-13,而且是使用ios登录的

示例1

输入

drop table if exists login;
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 `user` (
`id` int(4) NOT NULL,
`name` 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 login VALUES
(1,2,1,'2020-10-12'),
(2,3,2,'2020-10-12'),
(3,2,2,'2020-10-13'),
(4,3,2,'2020-10-13');

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

INSERT INTO client VALUES
(1,'pc'),
(2,'ios'),
(3,'anroid'),
(4,'h5');

输出

fh|ios|2020-10-13
wangchao|ios|2020-10-13
select b.name as u_n,c.name as c_n,a.date
from login a
inner join user b
inner join client c
inner join (select user_id,max(date) as date from login
group by user_id ) d
on a.user_id=b.id
and a.client_id=c.id
and a.user_id=d.user_id
where a.date=d.date
order by b.name

11行代码搞定!
发表于 2025-03-27 15:53:10 回复(0)
select u.name u_n,c.name c_n, date
from login l join user u on l.user_id = u.id
join client c on l.client_id = c.id
where (user_id,date) in (select user_id,max(date) from login group by user_id)
order by u.name
发表于 2025-03-26 15:37:51 回复(0)
这个题有点意思,一不注意就踩坑:
查询数据:
fh    pc    2020-10-13
wangchao    ios    2020-10-13

SQL(错误)
select
    u.name as u_n,
    c.name as c_n,
    max(date) as date
from
    login l
inner join `user` u on
    u.id = l.user_id
inner join client c on
    c.id = l.client_id
group by
    l.user_id
order by
u.name;
发表于 2025-03-10 10:31:23 回复(0)
窗口函数果然yyds
with res as (select
u.name as u_n,
c.name as c_n,
date,
row_number() over(partition by u.name order by date desc) as ranking
from login l
join user u on l.user_id=u.id
join client c on l.client_id=c.id)

select
u_n,
c_n,
date
from res where ranking=1
发表于 2025-03-03 19:21:15 回复(0)
写了第一解法发现错误,理由是c.name无法聚合,因为里面的值不是一样的
select u.name u_n, c.name c_n, max(date)
from login l left join user u on l.user_id = u.id 
    left join client c on l.client_id = c.id
group by l.user_id
order by u_n
修正后用其他解法
select u.name u_n, c.name c_n, date
from login l left join user u on l.user_id = u.id 
    left join client c on l.client_id = c.id
where (user_id, date) in (select user_id, max(date) from login group by user_id) 
order by u_n



发表于 2025-02-22 19:47:55 回复(1)
select
    user.name u_n,
    client.name c_n,
    login.date date
from
    login
    inner join user on login.user_id = user.id
    join client on login.client_id = client.id
where
    (user.name, date) in (
        select
            u.name,
            max(date)
        from
            login l
            inner join user u on l.user_id = u.id
            join client c on l.client_id = c.id
        group by
            u.name
    )
order by
    u_n

发表于 2025-01-07 18:04:33 回复(0)

利用窗口函数给每个user_id按时间倒序排序,取出排名第一即可
select name_1  u_n
        ,name_2   c_n
      ,date
from(
      select u.name name_1
              ,c.name name_2
             ,date
             ,row_number()over(partition by user_id order by date desc) r --根据date倒序排序 r=1即最近时间
              from login l
             join user u
             on l.user_id=u.id
            join client c
            on l.client_id=c.id
         ) a
where r =1
order by u_n

发表于 2024-12-24 15:30:17 回复(0)
with
    t as (
        SELECT
            l.id,
            l.user_id,
            l.date,
            l.client_id,
            DENSE_RANK() OVER (
                PARTITION BY
                    l.user_id
                ORDER BY
                    l.date DESC
            ) AS ranking
        FROM
            login l
    )
SELECT
    u.name as u_n,
    c.name as c_n,
    t.date
from
    t
    JOIN client c on c.id = t.client_id
    join user u on u.id = t.user_id
WHERE
    t.ranking = 1
order by u.name asc

发表于 2024-10-17 10:06:17 回复(0)
SELECT u.name u_n, c.name c_n, date
FROM login l
JOIN user u ON l.user_id=u.id
JOIN client c ON l.client_id=c.id
WHERE (l.user_id,date) IN
(
    SELECT user_id,max(date)
    FROM login
    GROUP BY user_id
)
order by u_n
发表于 2024-09-19 10:11:03 回复(0)


select t1.name as u_n,t3.name as c_n,date_1
from
(
select user_id,name,date_1
from
(
select user_id,max(date) as date_1
from login
group by user_id
)a
left join
(
    select id,name from user
)b
on a.user_id = b.id

)t1
inner join
(
 select user_id,client_id,date from login
)t2
on t1.user_id = t2.user_id and t1.date_1 = t2.date
left join
(
    select id,name from client
)t3
on t2.client_id = t3.id
order by t1.name



发表于 2024-09-08 20:40:57 回复(0)
select u.name,c.name,l.date
from login l left join user u on u.id = l.user_id 
    left join client c on c.id = l.client_id
where (l.user_id,l.date) in(
    select user_id,max(date)
    from login
    group by user_id
)
order by u.name asc

发表于 2024-08-21 14:46:54 回复(0)
(1)通过登录(login)记录表,查询用户ID和用户最近登录的日期
select user_id, max(date) as date
from login
group by user_id 
(2)上述结果,连接登录(login)记录表,查询用户ID、端口ID和用户最近登录的日期
select t1.user_id as user_id, client_id, t1.date as date
from
(
select user_id, max(date) as date
from login
group by user_id    
) as t1
left join login
on t1.user_id = login.user_id and t1.date = login.date
(3)上述结果,连接其他两表(用户(user)表,客户端(client)表),查询用户的名字、设备的名字用户最近登录的日期
select user.name as u_n, client.name as c_n, t2.date as date
from
(
select t1.user_id as user_id, client_id, t1.date as date
from
(
select user_id, max(date) as date
from login
group by user_id    
) as t1
left join login
on t1.user_id = login.user_id and t1.date = login.date
) as t2

left join user
on t2.user_id = user.id

left join client
on t2.client_id = client.id

order by user.name;

发表于 2024-07-25 00:11:49 回复(0)
-- 使用first_value函数开窗,注意排序逻辑,以及distinct去重
select distinct u.name u_na
,first_value(c.name)over(partition by u.id order by date desc) c_n
,first_value(date)over(partition by u.id order by date desc) date
from login l
join user u
    on l.user_id=u.id
join client c
    on l.client_id=c.id
order by 1


发表于 2024-07-15 14:28:32 回复(0)

写的过于复杂了。。。。

select
    u.name u_n,
    c.name c_n,
    t2.date date
from (
    select
        user_id,
        client_id,
        date
    from (
        select
            *,
            row_number() over (partition by user_id order by date desc) rn
        from login
    ) t1
    where t1.rn=1
) t2 join user u
on t2.user_id=u.id
join client c
on t2.client_id=c.id
order by u_n
发表于 2024-06-10 18:41:13 回复(0)
select u.name as u_n,c.name as c_n,date
date
from login as l
join user u on u.id=l.user_id
join client c on c.id=l.client_id
where (user_id,date) in(select user_id,max(date) from login group by user_id)
order by 1

发表于 2024-05-28 13:54:06 回复(0)
with p as(
select t1.name as u_n,t2.name as c_n,t.date as date 
from login as t
left join user as t1
on t.user_id = t1.id
left join client as t2
on t.client_id = t2.id
),
q as(
select u_n,c_n,date,rank() over(partition by u_n order by date desc) as rk 
from p
)

select u_n,c_n,date from q
where rk = 1;

发表于 2024-05-09 11:40:32 回复(0)

问题信息

SQL
难度:
205条回答 5022浏览

热门推荐

通过挑战的用户

查看代码

相关试题

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