SQL 面试真题 · 步骤可视化
WITH ranked AS ( SELECT user_id, login_date, ROW_NUMBER() OVER(PARTITION BY user_id ORDER BY login_date) AS rn FROM user_login ) SELECT user_id, COUNT(*) AS consecutive_days FROM ranked GROUP BY user_id, DATE_SUB(login_date, rn);
WITH ranked AS ( SELECT user_id, login_date, ROW_NUMBER() OVER(PARTITION BY user_id ORDER BY login_date) AS rn FROM user_login ) SELECT user_id, COUNT(*) AS consecutive_days FROM ranked GROUP BY user_id, DATE_SUB(login_date, INTERVAL rn DAY);
WITH ranked AS ( SELECT user_id, login_date, rowNumberInAllBlocks() OVER(PARTITION BY user_id ORDER BY login_date) AS rn FROM user_login ) SELECT user_id, count(*) AS consecutive_days FROM ranked GROUP BY user_id, subtractDays(login_date, rn);
SELECT u.register_date, DATEDIFF(l.login_date, u.register_date) AS retention_day, COUNT(DISTINCT u.user_id) AS retained_users FROM (SELECT DISTINCT user_id, register_date FROM user_activity) u LEFT JOIN user_activity l ON u.user_id = l.user_id AND l.login_date >= u.register_date WHERE DATEDIFF(l.login_date, u.register_date) <= 90 GROUP BY 1, 2
SELECT u.register_date, dateDiff('day', u.register_date, l.login_date) AS retention_day, uniqExact(u.user_id) AS retained_users FROM (SELECT DISTINCT user_id, register_date FROM user_activity) u LEFT JOIN user_activity l ON u.user_id = l.user_id AND l.login_date >= u.register_date WHERE dateDiff('day', u.register_date, l.login_date) <= 90 GROUP BY 1, 2
| date | amount |
|---|---|
| Day 1 | 100 |
| Day 2 | 150 |
| Day 3 | 200 |
| Day 4 | 80 |
SELECT date, amount, SUM(amount) OVER( ORDER BY date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) AS cumulative_sum FROM daily_sales;
| student | subject | score |
|---|---|---|
| 张三 | 数学 | 95 |
| 张三 | 语文 | 88 |
| 张三 | 英语 | 92 |
| student | 数学 | 语文 | 英语 |
|---|---|---|---|
| 张三 | 95 | 88 | 92 |
SELECT student, MAX(CASE WHEN subject = '数学' THEN score END) AS 数学, MAX(CASE WHEN subject = '语文' THEN score END) AS 语文, MAX(CASE WHEN subject = '英语' THEN score END) AS 英语 FROM scores GROUP BY student;
| student | 数学 | 语文 | 英语 |
|---|---|---|---|
| 张三 | 95 | 88 | 92 |
| student | subject | score |
|---|---|---|
| 张三 | 数学 | 95 |
| 张三 | 语文 | 88 |
| 张三 | 英语 | 92 |
SELECT t.student, m.subject, CASE m.subject WHEN '数学' THEN t.数学 WHEN '语文' THEN t.语文 WHEN '英语' THEN t.英语 END AS score FROM scores t CROSS JOIN ( SELECT '数学' AS subject UNION ALL SELECT '语文' UNION ALL SELECT '英语' ) m;
WITH events AS ( SELECT user_id, 1 AS change, login_time AS time FROM user_log UNION ALL SELECT user_id, -1 AS change, logout_time AS time FROM user_log ), running_total AS ( SELECT time, SUM(change) OVER (ORDER BY time) AS online_cnt FROM events ) SELECT MAX(online_cnt) AS max_peak FROM running_total;