跳到内容
当前位置:首页>面试真题>大厂SQL面试通关秘籍:腾讯/字节/阿里/美团/京东真题详解

大厂SQL面试通关秘籍:腾讯/字节/阿里/美团/京东真题详解

  • 2026-09-18 20:15:38
大厂SQL面试通关秘籍:腾讯/字节/阿里/美团/京东真题详解

对于想进入互联网大厂的数据分析师来说,SQL是面试中必考的硬技能。本文精选了腾讯、字节跳动、阿里巴巴、美团、京东五家大厂的典型SQL面试题,每家公司2-3道,帮助你提前做好准备。


一、腾讯篇

题目1:连续登录天数统计

场景:用户登录表 user_login,包含字段 user_id(用户ID)、login_date(登录日期)。

要求:查询每个用户连续登录的最大天数。

示例数据:

user_id
login_date
A
2024-01-01
A
2024-01-02
A
2024-01-04
B
2024-01-01
B
2024-01-02
B
2024-01-03

参考答案:

WITH login_with_grp AS (    SELECT        user_id,        login_date,        DATE_SUB(login_date, INTERVAL            ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY login_date) DAY        ) AS grp    FROM user_login)SELECT    user_id,grp,    COUNT(*) AS continuous_daysFROM login_with_grpGROUP BY user_id, grpORDER BY continuous_days DESCLIMIT 1;

考点解析:

  • • 使用 ROW_NUMBER() 窗口函数生成序号
  • • 用日期减去序号,连续日期的差值相同,形成分组标识
  • • 按用户和分组标识聚合,统计每组天数

题目2:分组TopN问题

场景:订单表 orders,包含 user_id、order_id、amount、order_time。

要求:查询每个用户金额最高的前3笔订单。

参考答案:

SELECT user_id, order_id, amount, order_timeFROM (    SELECT        user_id,        order_id,        amount,        order_time,        ROW_NUMBER() OVER (PARTITION BY user_idORDER BY amount DESC        ) AS rn    FROM orders) tWHERE rn <= 3;

考点解析:

  • • ROW_NUMBER() 为每个分组内数据排序编号
  • • 外层筛选 rn <= 3 获取Top3
  • • 注意区分 ROW_NUMBER()、RANK()、DENSE_RANK() 的差异

题目3:用户留存率计算

场景:用户注册表 users(user_id, register_date)和用户活跃表 active(user_id, active_date)。

要求:计算每日新增用户的次日留存率、7日留存率。

参考答案:

WITH new_users AS (    SELECT        register_date,        COUNT(DISTINCT user_id) AS new_user_cnt    FROM users    GROUP BY register_date),retention AS (    SELECT        u.register_date,        COUNT(DISTINCT CASE            WHEN DATEDIFF(a.active_date, u.register_date) = 1            THEN a.user_id        END) AS d1_retained,        COUNT(DISTINCT CASE            WHEN DATEDIFF(a.active_date, u.register_date) = 7            THEN a.user_id        END) AS d7_retained    FROM users u    LEFT JOIN active a ON u.user_id = a.user_id    GROUP BY u.register_date)SELECT    n.register_date,    n.new_user_cnt,    ROUND(r.d1_retained * 100.0 / n.new_user_cnt, 2) AS d1_retention_rate,    ROUND(r.d7_retained * 100.0 / n.new_user_cnt, 2) AS d7_retention_rateFROM new_users nJOIN retention r ON n.register_date = r.register_date;

考点解析:

  • • 留存率是数据分析核心指标
  • • 使用 DATEDIFF 计算日期间隔
  • • CASE WHEN 条件计数实现留存统计

二、字节跳动篇

题目4:行列转换(行转列)

场景:学生成绩表 scores,包含 student_id、subject、score。

要求:将科目从行转为列,显示每个学生的各科成绩。

参考答案:

SELECT    student_id,    MAX(CASE WHEN subject = '数学' THEN score END) AS math_score,    MAX(CASE WHEN subject = '语文' THEN score END) AS chinese_score,    MAX(CASE WHEN subject = '英语' THEN score END) AS english_scoreFROM scoresGROUP BY student_id;

考点解析:

  • • 使用 CASE WHEN + 聚合函数实现行转列
  • • 也可用 PIVOT(部分数据库支持)

题目5:中位数计算

场景:员工薪资表 salary(employee_id, salary)。

要求:计算薪资的中位数。

参考答案:

SELECT AVG(salary) AS median_salaryFROM (    SELECT        salary,        ROW_NUMBER() OVER (ORDER BY salary) AS rn_asc,        ROW_NUMBER() OVER (ORDER BY salary DESC) AS rn_desc    FROM salary) tWHERE rn_asc BETWEEN rn_desc - 1 AND rn_desc + 1;

考点解析:

  • • 利用正序和倒序序号相等或相邻的特性定位中位数
  • • 奇数条记录取中间值,偶数条记录取中间两个的平均

题目6:漏斗分析

场景:用户行为表 user_actions,包含 user_id、action(步骤:view/click/order/pay)、action_time。

要求:计算从浏览到支付的各环节转化率。

参考答案:

WITH funnel AS (    SELECT        user_id,        MAX(CASE WHEN action = 'view' THEN 1 END) AS viewed,        MAX(CASE WHEN action = 'click' THEN 1 END) AS clicked,        MAX(CASE WHEN action = 'order' THEN 1 END) AS ordered,        MAX(CASE WHEN action = 'pay' THEN 1 END) AS paid    FROM user_actions    GROUP BY user_id)SELECT    SUM(viewed) AS view_cnt,    SUM(clicked) AS click_cnt,    SUM(ordered) AS order_cnt,    SUM(paid) AS pay_cnt,    ROUND(SUM(clicked) * 100.0 / SUM(viewed), 2) AS view_to_click,    ROUND(SUM(ordered) * 100.0 / SUM(clicked), 2) AS click_to_order,    ROUND(SUM(paid) * 100.0 / SUM(ordered), 2) AS order_to_pay,    ROUND(SUM(paid) * 100.0 / SUM(viewed), 2) AS total_conversionFROM funnel;

考点解析:

  • • 漏斗分析是互联网产品分析的核心场景
  • • 使用条件聚合统计各步骤用户数
  • • 计算相邻步骤及整体转化率

三、阿里巴巴篇

题目7:累计求和与移动平均

场景:每日销售额表 daily_sales(sale_date, amount)。

要求:计算每日销售额、累计销售额、近7日移动平均。

参考答案:

SELECT    sale_date,    amount,    SUM(amount) OVER (ORDER BY sale_date) AS cumulative_amount,    AVG(amount) OVER (        ORDER BY sale_date        ROWS BETWEEN 6 PRECEDING AND CURRENT ROW    ) AS moving_avg_7dFROM daily_sales;

考点解析:

  • • SUM() OVER 实现累计求和
  • • ROWS BETWEEN 定义窗口范围计算移动平均

题目8:环比/同比增长率

场景:月度销售表 monthly_sales(year_month, sales_amount)。

要求:计算每月销售额的环比增长率和同比增长率。

参考答案:

WITH sales_with_lag AS (    SELECT        year_month,        sales_amount,        LAG(sales_amount, 1) OVER (ORDER BY year_month) AS last_month,        LAG(sales_amount, 12) OVER (ORDER BY year_month) AS last_year    FROM monthly_sales)SELECT    year_month,    sales_amount,    ROUND((sales_amount - last_month) * 100.0 / last_month, 2) AS mom_growth,    ROUND((sales_amount - last_year) * 100.0 / last_year, 2) AS yoy_growthFROM sales_with_lag;

考点解析:

  • • LAG() 函数获取前N行数据
  • • 环比(MoM)对比上月,同比(YoY)对比去年同月

题目9:用户分层(RFM模型)

场景:用户消费表 user_transactions(user_id, order_date, amount)。

要求:根据最近消费时间(Recency)、消费频率(Frequency)、消费金额(Monetary)对用户分层。

参考答案:

WITH rfm AS (    SELECT        user_id,        DATEDIFF(CURRENT_DATE, MAX(order_date)) AS recency,        COUNT(DISTINCT order_date) AS frequency,        SUM(amount) AS monetary    FROM user_transactions    WHERE order_date >= DATE_SUB(CURRENT_DATE, INTERVAL 1 YEAR)    GROUP BY user_id),rfm_score AS (    SELECT        user_id,        recency, frequency, monetary,        NTILE(5) OVER (ORDER BY recency DESC) AS r_score,        NTILE(5) OVER (ORDER BY frequency) AS f_score,        NTILE(5) OVER (ORDER BY monetary) AS m_score    FROM rfm)SELECT    user_id,    recency, frequency, monetary,    r_score, f_score, m_score,    CASE        WHEN r_score >= 4 AND f_score >= 4 AND m_score >= 4 THEN '重要价值客户'        WHEN r_score >= 4 AND f_score >= 4 THEN '重要保持客户'        WHEN r_score >= 4 AND m_score >= 4 THEN '重要发展客户'        WHEN f_score >= 4 AND m_score >= 4 THEN '重要挽留客户'        ELSE '一般客户'    END AS user_segmentFROM rfm_score;

考点解析:

  • • RFM是经典的用户价值分层模型
  • • NTILE() 将数据分为N等份,便于打分
  • • 根据R、F、M得分组合定义用户标签

四、美团篇

题目10:时段订单分布

场景:订单表 orders(order_id, order_time, amount)。

要求:统计每小时的订单量和销售额分布。

参考答案:

SELECT    HOUR(order_time) AS hour_of_day,    COUNT(*) AS order_cnt,    SUM(amount) AS total_amount,    ROUND(AVG(amount), 2) AS avg_amountFROM ordersWHERE order_time >= DATE_SUB(CURRENT_DATE, INTERVAL 7 DAY)GROUP BY HOUR(order_time)ORDER BY hour_of_day;

考点解析:

  • • HOUR() 提取时间的小时部分
  • • 时段分析常用于运营策略制定

题目11:商家销售额排名

场景:订单表 orders(merchant_id, order_id, amount)。

要求:查询销售额Top10的商家,并显示其排名。

参考答案:

WITH merchant_sales AS (    SELECT        merchant_id,        SUM(amount) AS total_sales,        RANK() OVER (ORDER BY SUM(amount) DESC) AS sales_rank    FROM orders    GROUP BY merchant_id)SELECT merchant_id, total_sales, sales_rankFROM merchant_salesWHERE sales_rank <= 10;

考点解析:

  • • 先聚合再排序,注意窗口函数在聚合后的使用
  • • RANK() 处理并列排名

题目12:复购率计算

场景:订单表 orders(user_id, order_id, order_time)。

要求:计算每月的新客数和复购率。

参考答案:

WITH user_first_order AS (    SELECT        user_id,        DATE_FORMAT(MIN(order_time), '%Y-%m') AS first_month    FROM orders    GROUP BY user_id),monthly_stats AS (    SELECT        DATE_FORMAT(o.order_time, '%Y-%m') AS month,        COUNT(DISTINCT o.user_id) AS total_users,        COUNT(DISTINCT CASE            WHEN u.first_month = DATE_FORMAT(o.order_time, '%Y-%m')            THEN o.user_id        END) AS new_users    FROM orders o    JOIN user_first_order u ON o.user_id = u.user_id    GROUP BY DATE_FORMAT(o.order_time, '%Y-%m'))SELECT    month,    total_users,    new_users,    total_users - new_users AS returning_users,    ROUND((total_users - new_users) * 100.0 / total_users, 2) AS repurchase_rateFROM monthly_stats;

考点解析:

  • • 先找出每个用户的首次购买月份
  • • 通过对比判断新客还是老客
  • • 复购率 = 老客数 / 总用户数

五、京东篇

题目13:库存周转天数

场景:商品库存表 inventory(sku_id, date, stock_qty)和销售表 sales(sku_id, date, sale_qty)。

要求:计算每个SKU近30天的平均库存周转天数。

参考答案:

WITH daily_data AS (    SELECT        i.sku_id,        i.date,        i.stock_qty,        COALESCE(s.sale_qty, 0) AS sale_qty    FROM inventory i    LEFT JOIN sales s ON i.sku_id = s.sku_id AND i.date = s.date    WHERE i.date >= DATE_SUB(CURRENT_DATE, INTERVAL 30 DAY)),sku_stats AS (    SELECT        sku_id,        AVG(stock_qty) AS avg_stock,        SUM(sale_qty) AS total_sales    FROM daily_data    GROUP BY sku_id)SELECT    sku_id,    avg_stock,    total_sales,    CASE        WHEN total_sales = 0 THEN NULL        ELSE ROUND(avg_stock * 30 / total_sales, 2)    END AS turnover_daysFROM sku_stats;

考点解析:

  • • 库存周转天数 = 平均库存 / 日均销量
  • • 电商供应链分析的核心指标

题目14:异常订单检测

场景:订单表 orders(user_id, order_id, amount, order_time)。

要求:找出疑似刷单的用户(1小时内下单超过5次或单日消费超过平均3倍)。

参考答案:

WITH user_stats AS (    SELECT        user_id,        DATE(order_time) AS order_date,        COUNT(*) AS order_cnt,        SUM(amount) AS daily_amount,        AVG(amount) AS avg_order_amount    FROM orders    GROUP BY user_id, DATE(order_time)),hourly_stats AS (    SELECT        user_id,        DATE_FORMAT(order_time, '%Y-%m-%d %H:00:00') AS hour_slot,        COUNT(*) AS hourly_cnt    FROM orders    GROUP BY user_id, DATE_FORMAT(order_time, '%Y-%m-%d %H:00:00')),avg_stats AS (    SELECT AVG(daily_amount) AS overall_avg_amount    FROM user_stats)SELECT DISTINCT    u.user_id,    '高频下单' AS risk_typeFROM hourly_stats hWHERE h.hourly_cnt > 5UNIONSELECT DISTINCT    u.user_id,    '异常高额' AS risk_typeFROM user_stats u left join avg_stats a on 1=1WHERE u.daily_amount > a.overall_avg_amount * 3;

考点解析:

  • • 风控场景常用SQL分析
  • • 多维度异常检测(频率、金额)
  • • 使用 UNION 合并不同规则的异常用户

面试准备建议

1. 核心知识点

知识点
重要性
典型题目
窗口函数
⭐⭐⭐⭐⭐
TopN、累计求和、排名
日期函数
⭐⭐⭐⭐⭐
留存分析、同比环比
行列转换
⭐⭐⭐⭐
透视表、报表生成
递归查询
⭐⭐⭐
树形结构、层级数据
性能优化
⭐⭐⭐⭐
索引、执行计划分析

2. 常见考点总结

窗口函数必会:

  • • ROW_NUMBER() / RANK() / DENSE_RANK() —— 排名类问题
  • • LAG() / LEAD() —— 同比环比、前后行对比
  • • SUM() OVER / AVG() OVER —— 累计、移动计算

业务场景必会:

  • • 留存率计算(次日、7日、30日)
  • • 漏斗分析(转化率)
  • • RFM用户分层
  • • 复购率、活跃度统计

3. 面试技巧

  1. 1. 先理解业务场景:明确题目要求,不清楚的地方及时提问
  2. 2. 写出思路再写SQL:先用伪代码或文字描述逻辑
  3. 3. 考虑边界情况:空值处理、数据异常、性能优化
  4. 4. 熟悉你的简历:写上去的SQL项目要能讲清楚

结语

SQL是数据分析师的基本功,大厂面试中SQL考核通常占30%-50%的比重。建议大家在理解这些真题的基础上,多动手练习,形成自己的解题思路。

练习资源推荐:

  • • LeetCode Database 题目
  • • 牛客网 SQL 专项练习
  • • 自己搭建测试数据模拟业务场景

祝各位面试顺利,早日拿到心仪的大厂offer!


本文作者:鹏哥数个数专注数据分析与职场成长,欢迎关注交流!   #互联网大厂 #面试题 #hivesql #sql面试题 #数据分析 #数据分析师 #窗口函数 #腾讯 #京东 #字节 #美团 #阿里巴巴 #SQL面试真题