首页 > 试题广场 >

推荐内容准确的用户平均评分

[编程题]推荐内容准确的用户平均评分
  • 热度指数:42409 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
某产品2022年2月8日系统推荐内容给部分用户的数据,以及用户信息和对推荐内容的评分交叉表部分数据如下:
推荐内容表recommend_tb(rec_id-推荐信息id,rec_info_l-推荐信息标签,rec_user-推荐目标用户id,rec_time-推荐时间,如下所示:
rec_id rec_info_l rec_user rec_time
1 健身 101 2022-02-08 07:23:15
2 美妆 102 2022-02-08 07:24:15
3 体育 103 2022-02-08 07:25:15
4 美妆 103 2022-02-08 07:26:15
5 政要 104 2022-02-08 07:27:15
6 体育 104 2022-02-08 07:28:15
7 体育 105 2022-02-08 07:29:15
8 影视 106 2022-02-08 07:30:15
用户信息及评分交叉表user_action_tbuser_id-用户id,hobby_l-用户喜好标签,score-综合评分),如下所示:
注:该表score为对所有推荐给该用户的内容的综合评分,在计算用户平均评分切勿将推荐次数作为分母
user_id hobby_l score
101 健身 88
102 影视 81
103 美妆 78
104 健身 68
105 体育 90
106 影视 82

问题:请统计推荐内容准确的用户平均评分?(结果保留3位小数)
注:(1)准确的定义:推荐的内容标签与用户喜好标签一致;如推荐多次给同一用户,有一次及以上准确就归为准确。
示例数据结果如下:
avg_score
84.500
解释:一共推荐8条内容,其中推荐给101、103、105、106四位用户的内容准确,
四位用户的评分分别是88、78、90、82,故平均评分=(88+78+90+82)/4=84.500
(2)如果同一用户推荐同一个内容标签的话,计算的时候只算一次。
示例1

输入

drop table if exists  `recommend_tb` ; 
CREATE TABLE `recommend_tb` (
`rec_id` int(11) NOT NULL,
`rec_info_l` varchar(8) NOT NULL,
`rec_user` int(11) NOT NULL,
`rec_time` datetime NOT NULL,
PRIMARY KEY (`rec_id`));
INSERT INTO recommend_tb VALUES(1,'健身',101,'2022-02-08 07:23:15');
INSERT INTO recommend_tb VALUES(2,'美妆',102,'2022-02-08 07:24:15');
INSERT INTO recommend_tb VALUES(3,'体育',103,'2022-02-08 07:25:15');
INSERT INTO recommend_tb VALUES(4,'美妆',103,'2022-02-08 07:26:15');
INSERT INTO recommend_tb VALUES(5,'政要',104,'2022-02-08 07:27:15');
INSERT INTO recommend_tb VALUES(6,'体育',104,'2022-02-08 07:28:15');
INSERT INTO recommend_tb VALUES(7,'体育',105,'2022-02-08 07:29:15');
INSERT INTO recommend_tb VALUES(8,'影视',106,'2022-02-08 07:30:15');

drop table if exists  `user_action_tb` ;   
CREATE TABLE `user_action_tb` (
`user_id` int(11) NOT NULL,
`hobby_l` varchar(8) NOT NULL,
`score` int(11) NOT NULL,
PRIMARY KEY (`user_id`));
INSERT INTO user_action_tb VALUES(101,'健身',88);
INSERT INTO user_action_tb VALUES(102,'影视',81);
INSERT INTO user_action_tb VALUES(103,'美妆',78);
INSERT INTO user_action_tb VALUES(104,'健身',68);
INSERT INTO user_action_tb VALUES(105,'体育',90);
INSERT INTO user_action_tb VALUES(106,'影视',82);

输出

84.500
with t1 as(
    select distinct rt.rec_info_l, rt.rec_user, uat.score
    from recommend_tb rt
    join 
    user_action_tb uat
    on rt.rec_info_l=uat.hobby_l
    and rt.rec_user=uat.user_id
)

select round(avg(score),3) as avg_score
from t1


Edit 2024-03-24
with t1 as(
    SELECT DISTINCT user_id,
    IF(rec_info_l = hobby_l, 1, 0) as flag,   # 判断推荐是否正确
    score
    FROM recommend_tb
    LEFT JOIN user_action_tb
    ON recommend_tb.rec_user = user_action_tb.user_id
)

SELECT ROUND(AVG(score), 3) as avg_score
from t1
WHERE flag = 1



编辑于 2025-03-24 19:02:21 回复(2)
最后一题是真抽象,如果比如103喜欢美妆,如果重复推荐两次美妆给103,只统计一次,所以要用distinct
SELECT ROUND(AVG(score), 3) as avg_score
FROM (
    SELECT DISTINCT user_id,
    IF(rec_info_l = hobby_l, 1, 0) as flag,   # 判断推荐是否正确
    score
    FROM recommend_tb
    LEFT JOIN user_action_tb
    ON recommend_tb.rec_user = user_action_tb.user_id
) as t1
WHERE flag = 1


发表于 2024-09-12 21:28:30 回复(2)
想问下佬们这么写为什么有组用例不通过?
select sum(score)/count(distinct a.rec_user) as avg_score
from recommend_tb a
left join user_action_tb b
on a.rec_user = b.user_id
where a.rec_info_l = b.hobby_l
发表于 2025-03-18 13:00:01 回复(4)
select avg(score)
from user_action_tb u
inner join recommend_tb r
on r.rec_user = u.user_id
and r.rec_info_l=u.hobby_l
编辑于 2024-04-07 14:15:52 回复(4)
select distinct r.rec_user from recommend_tb r
left join user_action_tb u on r.rec_user	 = u.user_id
where r.rec_info_l = u.hobby_l
先得到推荐准确的这部分用户的ID:

然后在用户表中,计算平均得分。where筛选出第一段代码中的这部分用户即可
select avg(score) avg_score from user_action_tb
where user_id in 
(select distinct r.rec_user from recommend_tb r
left join user_action_tb u on r.rec_user	 = u.user_id
where r.rec_info_l = u.hobby_l)


发表于 2025-01-01 16:11:09 回复(0)
select round(avg(score),3) avg_score
from (
        select distinct(rec_user),score
        from 
            recommend_tb rt join user_action_tb uat 
            on rt.rec_user=uat.user_id
        where rec_info_l=hobby_l
) t ;

发表于 2024-12-18 10:21:03 回复(0)
select round(avg(score),3) avg_score
from user_action_tb
where (user_id,hobby_l)
in
(select rec_user user_id,rec_info_l hobby_l from recommend_tb)
发表于 2024-08-26 21:24:18 回复(2)
题目第二个注释的意思是,假如向同一个用户推送同一种内容的次数多于1次,也算作1次。
具体来说就是在recommend_tb中,出现了rec_info_l和rec_user都相同的多笔不同的记录。
发表于 2025-03-03 16:30:24 回复(0)
select round(avg(c.score),3) from (select  distinct user_id,score from recommend_tb join user_action_tb on rec_user=user_id where rec_info_l=hobby_l) as c ;
发表于 2025-02-25 15:53:08 回复(0)
with t1 as (
    select
    distinct r.rec_info_l,r.rec_user, u.score
    from
    recommend_tb as r
    join
    user_action_tb as u
    on r.rec_info_l = u.hobby_l and r.rec_user = u.user_id
)

select
round(avg(t1.score),3) as avg_score
from t1
发表于 2025-02-14 16:34:45 回复(0)
select avg(a.score) from (select distinct u.user_id,score from
recommend_tb as r inner join user_action_tb as u on r.rec_info_l=u.hobby_l and r.rec_user=u.user_id) as a
发表于 2024-10-29 17:24:18 回复(0)
select 
avg(case when t.score>0 then t.score end) as avg_score
from
(select distinct
user_id, score
from recommend_tb
join user_action_tb
    on recommend_tb.rec_user = user_action_tb.user_id
    and recommend_tb.rec_info_l = user_action_tb.hobby_l
) t
-- 是出现了相同用户相同记录,出现了两条记录吧,这种是数仓的问题吧,但我们还是需要尽量去避免?

发表于 2024-08-22 10:44:06 回复(3)
服了,要distinct
select sum(score)/count(score) from(
select distinct rec_user,rec_info_l,b.score score from recommend_tb a
left join
(
    select user_id,hobby_l,score from user_action_tb
) b on rec_user=user_id and rec_info_l=hobby_l
 where b.user_id is not null and hobby_l is not null
) a

发表于 2025-06-12 16:14:58 回复(0)
with
    t1 as (
        select distinct
            rec_info_l,
            rec_time,
            hobby_l,
            score
            ,rec_user
        from
            recommend_tb r
            left join user_action_tb u on r.rec_user = u.user_id
        where
            rec_info_l = hobby_l
    )
select
   avg(score)
from
    t1
为什么写出来取到的id和分数都对,但是avg(score)就不对了,求问一下大佬我这里哪里出错了

发表于 2025-06-11 13:07:21 回复(0)
select
    avg(score1) as avg_score
from (
select
    avg(score) as score1
from recommend_tb as r
join user_action_tb as u
on r.rec_user = u.user_id
where rec_info_l = hobby_l
group by r.rec_user) as t
发表于 2025-06-10 21:47:55 回复(0)
select avg(score) avg_score
from
(select distinct rec_user,score
from recommend_tb r join user_action_tb u on r.rec_user=u.user_id
and r.rec_info_l=u.hobby_l) a
发表于 2025-06-08 15:23:51 回复(0)
WITH
    t1 AS (
        SELECT
            rt.rec_user,
            AVG(uat.score) AS user_score
        FROM
            recommend_tb AS rt
            LEFT JOIN user_action_tb AS uat ON rt.rec_user = uat.user_id
        WHERE
            rt.rec_info_l = uat.hobby_l
        GROUP BY
            rt.rec_user
    )

SELECT
    AVG(user_score) AS avg_score
FROM
    t1
发表于 2025-06-08 14:51:49 回复(0)
select
sum(score)/count(rec_user) avg_score
from
(
    select
    rec_user
    ,score
    from recommend_tb rt
    left join user_action_tb ua
    on rt.rec_user = ua.user_id
    and rt.rec_info_l = ua.hobby_l
    group by 1,2
    having sum(if(rec_info_l = hobby_l,1,0)) >= 1
) a

发表于 2025-06-05 17:14:24 回复(0)
with
    k as (
        select distinct
            rec_info_l,
            rec_user
        from
            recommend_tb
    ),
    k1 as (
        select
            rec_info_l,
            rec_user,
            score
        from
            k
            left join user_action_tb a on a.user_id = k.rec_user
            and k.rec_info_l = a.hobby_l
    )
select
    round(avg(score), 3)
from
    k1
where
    score is not NULL

发表于 2025-05-29 14:54:47 回复(0)
select
round(avg(a.score), 3) avg_score
from
(
select
rec_user
,score
from recommend_tb rt
join user_action_tb uat
on rt.rec_user = uat.user_id
and rt.rec_info_l = uat.hobby_l
group by 1
) a
发表于 2025-05-29 13:12:27 回复(0)