首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >SQL 文章UV和PV统计:COUNT DISTINCT + COUNT(腾讯面试题)

SQL 文章UV和PV统计:COUNT DISTINCT + COUNT(腾讯面试题)

作者头像
数据仓库晨曦
发布2026-07-23 21:31:20
发布2026-07-23 21:31:20
110
举报
文章被收录于专栏:数据仓库技术数据仓库技术

一、题目背景

这道题来自腾讯新闻/腾讯视频等内容业务的数据分析岗面试。PV(页面浏览量)和UV(独立访客数)是内容平台最基础的指标体系——PV衡量内容的总曝光量,UV衡量覆盖了多少独立用户。两者的比值 PV/UV 代表人均阅读次数,是衡量内容"粘性"的关键指标。

业务场景:腾讯新闻的编辑每天要看"昨日文章PV/UV排行榜",决定今天头条推什么。运营团队则通过 PV/UV 比值判断文章是否"标题党"——PV很高但UV一般,说明同一批用户反复点进来又出去。

二、题目

现有一张文章阅读日志表 t9_article_read_log,记录了用户每次阅读文章的行为明细。请统计每篇文章的 PV(页面浏览量)UV(独立访客数),并计算每篇文章PV占总PV的比例。按照PV降序排列。

  • PV(Page View):文章被阅读的总次数,同一用户多次阅读算多次
  • UV(Unique Visitor):文章的独立访客数,同一用户多次阅读只算1次

文章阅读日志表 t9_article_read_log:

代码语言:javascript
复制
+----------+-------------+----------------------+
| user_id  | article_id  |      read_time       |
+----------+-------------+----------------------+
| u01      | A001        | 2023-03-01 08:00:00  |
| u01      | A001        | 2023-03-01 09:00:00  |
| u01      | A002        | 2023-03-01 10:00:00  |
| u02      | A001        | 2023-03-01 11:00:00  |
| u02      | A003        | 2023-03-01 12:00:00  |
| u03      | A001        | 2023-03-01 13:00:00  |
| u03      | A002        | 2023-03-01 14:00:00  |
| u03      | A002        | 2023-03-01 15:00:00  |
| u04      | A001        | 2023-03-01 16:00:00  |
| u04      | A002        | 2023-03-02 08:00:00  |
| u05      | A003        | 2023-03-02 09:00:00  |
| u05      | A003        | 2023-03-02 10:00:00  |
| u05      | A003        | 2023-03-02 11:00:00  |
| u05      | A004        | 2023-03-02 12:00:00  |
+----------+-------------+----------------------+

三、思路分析

这是一道典型的聚合统计基础题,难度不高但考察对业务指标(PV/UV)的理解和SQL基础聚合函数的运用:

  • PV:使用 count(*)count(article_id) 统计总行数
  • UV:使用 count(distinct user_id) 统计去重后的用户数
  • article_id 分组 group by,按 PV 降序排列 order by

维度

评分

题目难度

⭐️

题目清晰度

⭐️⭐️⭐️⭐️⭐️

业务常见度

⭐️⭐️⭐️⭐️⭐️

四、逐步推导

1. 直接按文章ID分组统计PV和UV

执行SQL

代码语言:javascript
复制
select article_id,
       count(*)                as pv,  -- 页面浏览量
       count(distinct user_id) as uv   -- 独立访客数
from t9_article_read_log
group by article_id
order by pv desc

执行结果

代码语言:javascript
复制
+-------------+-----+-----+
| article_id  | pv  | uv  |
+-------------+-----+-----+
| A001        | 5   | 4   |
| A003        | 4   | 2   |
| A002        | 4   | 3   |
| A004        | 1   | 1   |
+-------------+-----+-----+
4 rows selected (9.002 seconds)(https://www.dwsql.com)

2. 计算每篇文章的PV占比

执行SQL

代码语言:javascript
复制
select article_id,
       pv,
       uv,
       round(pv / sum(pv) over (), 4) as pv_rate
from (
    select article_id,
           count(*)                as pv,
           count(distinct user_id) as uv
    from t9_article_read_log
    group by article_id
) t
order by pv desc

执行结果

代码语言:javascript
复制
+-------------+-----+-----+----------+
| article_id  | pv  | uv  | pv_rate  |
+-------------+-----+-----+----------+
| A001        | 5   | 4   | 0.3571   |
| A003        | 4   | 2   | 0.2857   |
| A002        | 4   | 3   | 0.2857   |
| A004        | 1   | 1   | 0.0714   |
+-------------+-----+-----+----------+
4 rows selected (1.108 seconds)(https://www.dwsql.com)

五、常见坑点

坑1:COUNT vs COUNT DISTINCT 别搞混

PV用 COUNT(*)(每次阅读算一次),UV用 COUNT(DISTINCT user_id)(每个用户只算一次)。这是两个SQL关键词的差异,也是两个业务指标的本质区别。面试中如果PV和UV都写了COUNT(*),基本直接挂。

坑2:DISTINCT 的性能代价

COUNT(DISTINCT user_id) 在大数据量下会触发全量去重,Shuffle数据量大时性能较差。如果数据量很大且允许近似值,可以考虑 approx_count_distinct()(Spark SQL)或 HyperLogLog 算法。

六、举一反三

  1. 人均PV(PV/UV):加一列 round(pv / uv, 2) as avg_pv_per_user,衡量每用户平均阅读次数
  2. 按时间维度统计:GROUP BY 加上 date 字段,按天看PV/UV趋势和周末效应
  3. 新老用户分层:关联用户表,按新用户/老用户分组统计PV/UV,对比两者的阅读行为差异
  4. 阅读深度:如果日志表有 read_duration(阅读时长),按阅读时长分段统计PV分布

七、知识点总结

考点

说明

COUNT(*) = PV

统计总行数,即页面总浏览量

COUNT(DISTINCT user_id) = UV

去重统计独立用户数

GROUP BY + ORDER BY

按文章分组并按PV降序排列

SUM() OVER() 占比

窗口函数一次扫描算全表总和,得到占比

八、建表语句和数据插入

代码语言:javascript
复制
CREATE TABLE t9_article_read_log (
    user_id    stringCOMMENT'用户ID',
    article_id stringCOMMENT'文章ID',
    read_time  stringCOMMENT'阅读时间'
) COMMENT'文章阅读日志表';

-- 数据插入
INSERTINTO t9_article_read_log VALUES
('u01', 'A001', '2023-03-01 08:00:00'),
('u01', 'A001', '2023-03-01 09:00:00'),
('u01', 'A002', '2023-03-01 10:00:00'),
('u02', 'A001', '2023-03-01 11:00:00'),
('u02', 'A003', '2023-03-01 12:00:00'),
('u03', 'A001', '2023-03-01 13:00:00'),
('u03', 'A002', '2023-03-01 14:00:00'),
('u03', 'A002', '2023-03-01 15:00:00'),
('u04', 'A001', '2023-03-01 16:00:00'),
('u04', 'A002', '2023-03-02 08:00:00'),
('u05', 'A003', '2023-03-02 09:00:00'),
('u05', 'A003', '2023-03-02 10:00:00'),
('u05', 'A003', '2023-03-02 11:00:00'),
('u05', 'A004', '2023-03-02 12:00:00');
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2026-07-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 数据仓库技术 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、题目背景
  • 二、题目
  • 三、思路分析
  • 四、逐步推导
    • 1. 直接按文章ID分组统计PV和UV
    • 2. 计算每篇文章的PV占比
  • 五、常见坑点
  • 六、举一反三
  • 七、知识点总结
  • 八、建表语句和数据插入
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档