首页 > 试题广场 >

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

[编程题]牛客每个人最近的登录日期(二)
  • 热度指数:164302 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
牛客每天有很多人登录,请你统计一下牛客每个用户最近登录是哪一天,用的是什么设备.
有一个登录(login)记录表,简况如下:
id user_id client_id date
1
2
3
4
2
3
2
3
1
2
2
2
2020-10-12
2020-10-12
2020-10-13
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
2
3
tm
fh
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 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)
SELECT 
    u.name AS u_n,
    c.name AS c_n,
    l2.date AS date
FROM(
    SELECT
    user_id,
    client_id,
    date,
    RANK()OVER(PARTITION BY user_id ORDER BY date DESC) AS rank_date
FROM login
) AS l2
JOIN user u 
    ON l2.user_id =  u.id
JOIN client c 
    ON l2.client_id = c.id
WHERE l2.rank_date = '1'
ORDER BY u.name;
用ROW_NUMBER函数同理
编辑于 2024-04-09 11:35:20 回复(0)
select t3.name,t4.name,t1.date
from
(select user_id,max(date) as date from login group by user_id) as t1
join login as t2 on t1.user_id=t2.user_id and t1.date=t2.date
join user as t3 on t2.user_id=t3.id
join client as t4 on t2.client_id=t4.id
order by t3.name

编辑于 2024-01-12 18:38:36 回复(0)
疯狂嵌套,叠叠乐 /笑哭
select
(select name from user where id=user_id) as u_n,
(select name from client where id=client_id) as c_n,
date
from login
where (user_id,date) in
(select user_id,max(date) from login group by user_id);
编辑于 2023-12-06 17:43:12 回复(0)
select
    t1.u_n,
    t1.c_n,
    t1.date
from
(
select 
    l.id,
    l.user_id,
    l.client_id,
    l.date,
    u.name as u_n,
    c.name as c_n,
    row_number() over(partition by l.user_id order by l.date desc) as rk
from login l 
left join user u on l.user_id = u.id
left join client c on l.client_id = c.id
) t1
where t1.rk = 1
order by t1.u_n asc

发表于 2023-11-26 19:08:52 回复(0)
一、表连接+max()函数
select u.name u_n, c.name c_n,xb.date from login l join
(select
user_id,
max(date) as date
from
login
group by
user_id) xb
on l.user_id=xb.user_id and l.date=xb.date
join client c on c.id=l.client_id join user u on l.user_id=u.id
order by u.name

二、窗口函数
select s.name u_n, c.name c_n,date 
from (select *,rank()over(partition by user_id order by date desc)  rk from login) xb
join user s on s.id=xb.user_id
join client c on c.id=xb.client_id
where rk=1
order by s.name
发表于 2023-11-20 15:23:28 回复(0)
select
  u_n,
  c_n,
  `date`
from
  (
    select
      u.name u_n,
      c.name c_n,
      `date`,
      rank() over (partition by user_id order by `date` desc) r
    from
      `login`
      inner join `user` u on user_id = u.id
      inner join client c on client_id = c.id
  ) t1
where
  t1.r = 1
order by u_n
1.利用窗口函数按用户分区,按日期逆序,最后排名,然后管理两个表查出各自的name;
2.最后筛选出排名是1的所有数据并按用户名排序
发表于 2023-10-25 10:39:18 回复(0)
第一次将窗口函数放在外查询里面,发现结果同一个用户,不同设备,R_date都是最新日期,人麻了。后面意识到需要一个where筛选出最新日期对应的用户和客户端,但是where执行顺序又在select之后,不能直接调用R_date,最后还是用了子查询……。不知道各位大佬有没有更高效的方法,望指教!
select  b.name,c.name,a.R_date
from (select *,max(login.date) over(partition by login.user_id) R_date from login) a
join user b on a.user_id=b.id
join client c on a.client_id=c.id
where a.date=a.R_date
order by b.name


发表于 2023-09-21 15:18:34 回复(0)
# 请你写出一个sql语句查询每个用户最近一天登录的日子,用户的名字,以及用户用的设备的名字,并且查询结果按照user的name升序排序,上面的例子查询结果如下:

with dwd_data as (
    select 
      user_id,
      client_id,
      date,
      row_number()over(partition by user_id order by date desc ) as rn
    from login t1
)

select
t2.name,
t3.name,
t1.date
from dwd_data t1
inner join user t2 on t1.user_id = t2.id 
inner join client t3 on t1.client_id = t3.id
where t1.rn =1
order by 1
;

发表于 2023-09-13 20:17:48 回复(0)
select u.name,c.name,d.date_time from(
select user_id,max(date) date_time from login group by user_id) d
left join login l on d.date_time = l.date and d.user_id = l.user_id
left join user u on d.user_id = u.id
left join client c on l.client_id = c.id
order by u.name asc

发表于 2023-05-06 14:46:12 回复(0)
with t1 as
(select distinct id, user_id,client_id, max(date) over (partition by user_id) as max_day
from login )
select distinct b.name as u_n, c.name as c_n, max_day
from t1 a 
join user b 
on a.user_id = b.id
join client c 
on a.client_id = c.id
where (user_id,client_id, max_day) in (select user_id,client_id,date 
                                      from login)
order by u_n;

发表于 2023-04-21 22:48:17 回复(0)
SELECT u.name AS u_n, c.name AS 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.date=(SELECT MAX(date) FROM login l2 WHERE l.user_id=l2.user_id)
ORDER BY u_n;
发表于 2023-04-09 20:28:32 回复(0)
先拿到每个用户最近的登录日期,然后表联结就行。
with t2 as (
    select * from(
        select *,max(date) over(partition by user_id) as last_date from login
    )t1
    where date=last_date
)

select user.name as u_n,
client.name  as c_n,t2.last_date as date
from t2
left join user on user.id=t2.user_id
left join client on client.id=t2.client_id
order by u_n asc


发表于 2023-03-23 21:12:40 回复(0)