一、表介绍 表 1: 阅读用户表 user_table 结构为: ds(日期) user_id(用户账号) book_id(书籍 id) readtime (阅读时长:ms) 示例数据 表 2 书籍分类表 book_table 结构为: book_id(书籍 id) book_name(书籍名称) category(书籍分类),其中 category 包括【男频】、【女频】、【出版】、【漫画】四类示例数据: 二、问题描述 问题 1:查询 2023-01-01 到 2023-01-07 期间阅读【出版】类书籍本数最多 10 个用户的user_id、其对应排名和阅读出版时长(分钟),结果要求是三个字段排名 ranks、用户 user_id、阅读时长readtime(分钟)问题 2:查询 2022-01-01 到 2022-01-07 期间只阅读了【男频】书籍的用户数,注意是只阅读男频,要求使用 left join 的方式实现,不要使用 not in 的方式 问题 3:查询 2022 年 1 月每天阅读次留率、阅读 7 留率、阅读 30 留率,其中阅读留存定义为用户某天阅读之后的第 N 天发生阅读,比如:1 号阅读 8 号再阅读则为阅读 7 留。结果要求一天一条数据,结果要求示例如下:
时间: 2024-04-11 14:25:59 浏览: 148
luntan.rar_user_info.frm
问题 1:
```sql
SELECT RANK() OVER (ORDER BY COUNT(DISTINCT ut.user_id) DESC) AS ranks,
ut.user_id,
SUM(ut.readtime)/60000 AS readtime
FROM user_table ut
JOIN book_table bt ON ut.book_id = bt.book_id
WHERE bt.category = '出版'
AND ut.ds BETWEEN '2023-01-01' AND '2023-01-07'
GROUP BY ut.user_id
ORDER BY ranks
LIMIT 10;
```
问题 2:
```sql
SELECT COUNT(DISTINCT ut.user_id) AS user_count
FROM user_table ut
LEFT JOIN book_table bt ON ut.book_id = bt.book_id AND bt.category <> '男频'
WHERE ut.ds BETWEEN '2022-01-01' AND '2022-01-07'
AND bt.book_id IS NULL;
```
问题 3:
```sql
WITH daily_read AS (
SELECT ds, user_id, COUNT(DISTINCT book_id) AS read_count
FROM user_table
WHERE ds BETWEEN '2022-01-01' AND '2022-01-31'
GROUP BY ds, user_id
),
day1_read AS (
SELECT ds, COUNT(DISTINCT user_id) AS day1_count
FROM daily_read
WHERE ds = '2022-01-01'
GROUP BY ds
),
day7_read AS (
SELECT dr1.ds, COUNT(DISTINCT dr1.user_id) AS day7_count
FROM daily_read dr1
JOIN daily_read dr2 ON dr1.user_id = dr2.user_id AND dr2.ds = DATE_ADD(dr1.ds, INTERVAL 7 DAY)
WHERE dr1.ds BETWEEN '2022-01-01' AND '2022-01-31'
GROUP BY dr1.ds
),
day30_read AS (
SELECT dr1.ds, COUNT(DISTINCT dr1.user_id) AS day30_count
FROM daily_read dr1
JOIN daily_read dr2 ON dr1.user_id = dr2.user_id AND dr2.ds = DATE_ADD(dr1.ds, INTERVAL 30 DAY)
WHERE dr1.ds BETWEEN '2022-01-01' AND '2022-01-31'
GROUP BY dr1.ds
)
SELECT dr.ds,
COALESCE(day7_count/day1_count, 0) AS day7_retention,
COALESCE(day30_count/day1_count, 0) AS day30_retention
FROM day1_read dr
LEFT JOIN day7_read dr7 ON dr.ds = dr7.ds
LEFT JOIN day30_read dr30 ON dr.ds = dr30.ds;
```
注意:以上是针对MySQL数据库的SQL查询语句,具体的数据库类型和语法可能有所不同,请根据实际情况进行调整。
阅读全文