大数据学习(132)-HIve数据分析

发布于:2025-06-07 ⋅ 阅读:(11) ⋅ 点赞:(0)

​​​​🍋🍋大数据学习🍋🍋

🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。
💖如果觉得博主的文章还不错的话,请点赞👍+收藏⭐️+留言📝支持一下博主哦🤞


一、连续值问题(如连续登录、连续消费)

核心思路
  1. 生成连续标识:通过 日期 - 行号 生成分组标识,连续日期的该值相同。
  2. 分组统计:按标识分组,统计连续长度。
典型例题

计算连续登录超过 7 天的用户 ID。

代码模板
WITH user_dates AS (
    -- 去重并生成行号
    SELECT 
        user_id,
        login_date,
        ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY login_date) AS rn
    FROM (
        SELECT DISTINCT user_id, login_date 
        FROM user_login
    ) t
),
date_groups AS (
    -- 生成连续标识
    SELECT 
        user_id,
        login_date,
        DATE_SUB(login_date, rn) AS date_group
    FROM user_dates
)
-- 筛选连续≥7天的用户
SELECT 
    user_id,
    MIN(login_date) AS start_date,
    MAX(login_date) AS end_date,
    COUNT(*) AS consecutive_days
FROM date_groups
GROUP BY user_id, date_group
HAVING COUNT(*) >= 7;

二、Top N 问题(如每个分组的前 N 条)

核心思路
  1. 窗口函数排名:用 ROW_NUMBER()/RANK()/DENSE_RANK() 生成排名。
  2. 过滤结果:筛选排名 ≤N 的记录。
典型例题

查询每个部门薪资最高的前 3 名员工。

代码模板
WITH ranked_employees AS (
    SELECT 
        dept_id,
        emp_id,
        salary,
        ROW_NUMBER() OVER (
            PARTITION BY dept_id 
            ORDER BY salary DESC
        ) AS rank
    FROM employees
)
SELECT *
FROM ranked_employees
WHERE rank <= 3;

三、时间窗口计算(同比 / 环比 / 移动平均)

核心思路
  1. 关联历史数据:用 JOIN 或窗口函数 LAG() 获取历史值。
  2. 计算差值 / 比例:如 (当前值 - 历史值)/历史值
典型例题

计算每月销售额的环比增长率。

代码模板
WITH monthly_sales AS (
    SELECT 
        YEAR(sale_date) AS sale_year,
        MONTH(sale_date) AS sale_month,
        SUM(amount) AS total_amount
    FROM sales
    GROUP BY YEAR(sale_date), MONTH(sale_date)
)
SELECT 
    curr.sale_year,
    curr.sale_month,
    curr.total_amount,
    prev.total_amount AS prev_month_amount,
    (curr.total_amount - prev.total_amount) / prev.total_amount AS mom_growth
FROM monthly_sales curr
LEFT JOIN monthly_sales prev 
ON curr.sale_month = prev.sale_month + 1 
AND curr.sale_year = prev.sale_year;

四、留存分析(N 日留存率)

核心思路
  1. 标记首次行为:用 MIN() 确定用户首次登录 / 注册日期。
  2. 关联后续行为:用 JOIN 或窗口函数判断是否在 N 日后仍活跃。
典型例题

计算 2023 年 1 月每日新增用户的 7 日留存率。

代码模板
WITH first_login AS (
    SELECT 
        user_id,
        MIN(login_date) AS first_date
    FROM user_login
    WHERE login_date >= '2023-01-01' AND login_date <= '2023-01-24'
    GROUP BY user_id
)
SELECT 
    fl.first_date,
    COUNT(DISTINCT fl.user_id) AS new_users,
    COUNT(DISTINCT ul.user_id) AS retained_users,
    COUNT(DISTINCT ul.user_id) / COUNT(DISTINCT fl.user_id) AS retention_rate_7d
FROM first_login fl
LEFT JOIN user_login ul 
ON fl.user_id = ul.user_id 
AND ul.login_date = DATE_ADD(fl.first_date, 7)
GROUP BY fl.first_date;

五、多表关联优化(大表 JOIN)

核心思路
  1. 过滤数据:在 JOIN 前用 WHERE 减少数据量。
  2. 使用 MapJoin:小表放右侧,触发 Map 端 JOIN。
  3. 分桶表优化:按 JOIN 字段分桶,提高数据分布均匀性。
典型例题

优化 orders(亿级)和 customers(百万级)的 JOIN。

代码模板
-- 方法1:手动 MapJoin(Hive 3.0+ 自动优化)
SELECT /*+ MAPJOIN(c) */
    o.order_id,
    c.customer_name
FROM orders o
JOIN customers c 
ON o.customer_id = c.customer_id
WHERE o.order_date >= '2023-01-01';

-- 方法2:分桶表优化
SET hive.optimize.skewjoin=true;
SELECT 
    o.order_id,
    c.customer_name
FROM orders_bucketed o
JOIN customers_bucketed c 
ON o.customer_id = c.customer_id;

六、数据倾斜处理

核心思路
  1. 拆分热点值:对高频 key 添加随机前缀,分两阶段聚合。
  2. 过滤异常值:排除导致倾斜的无效数据。
  3. 调整参数:增大 hive.groupby.skewindata
典型例题

优化 GROUP BY user_id 时的倾斜问题。

代码模板
-- 两阶段聚合
WITH stage1 AS (
    SELECT 
        CONCAT(user_id, '_', FLOOR(RAND() * 10)) AS tmp_key,
        COUNT(*) AS cnt
    FROM logs
    GROUP BY CONCAT(user_id, '_', FLOOR(RAND() * 10))
)
SELECT 
    SPLIT(tmp_key, '_')[0] AS user_id,
    SUM(cnt) AS total_cnt
FROM stage1
GROUP BY SPLIT(tmp_key, '_')[0];

七、JSON / 复杂类型处理

核心思路
  1. 解析 JSON:用 get_json_object() 或 json_tuple() 提取字段。
  2. 展开数组:用 LATERAL VIEW explode() 展开数组元素。
典型例题

解析 user_info 表中的 tags 字段(JSON 数组)。

代码模板
-- 解析 JSON 数组
SELECT 
    user_id,
    tag
FROM user_info
LATERAL VIEW explode(
    split(regexp_replace(tags, '[\\[\\]" ]', ''), ',')
) t AS tag;

-- 提取 JSON 对象字段
SELECT 
    user_id,
    get_json_object(user_info, '$.name') AS name,
    get_json_object(user_info, '$.age') AS age
FROM user_info;

八、累计计算(累计和、累计占比)

核心思路
  1. 窗口函数:用 SUM() OVER (ORDER BY ...) 实现累计聚合。
  2. 排序规则:确保 ORDER BY 与业务逻辑一致。
典型例题

计算每月累计销售额及累计占比。

代码模板
WITH monthly_sales AS (
    SELECT 
        YEAR(sale_date) AS sale_year,
        MONTH(sale_date) AS sale_month,
        SUM(amount) AS monthly_amount
    FROM sales
    GROUP BY YEAR(sale_date), MONTH(sale_date)
)
SELECT 
    sale_year,
    sale_month,
    monthly_amount,
    SUM(monthly_amount) OVER (
        PARTITION BY sale_year 
        ORDER BY sale_month
    ) AS cumulative_amount,
    SUM(monthly_amount) OVER (
        PARTITION BY sale_year 
        ORDER BY sale_month
    ) / SUM(monthly_amount) OVER (PARTITION BY sale_year) AS cumulative_ratio
FROM monthly_sales;

九、缺失值填充(连续日期补全)

核心思路
  1. 生成完整日期序列:用 LATERAL VIEW 和 SEQUENCE 函数。
  2. 左连接原数据:用 COALESCE() 填充缺失值。
典型例题

补全用户每日登录记录(无登录日填充为 0)。

代码模板
WITH all_dates AS (
    SELECT 
        user_id,
        DATE_ADD('2023-01-01', pos) AS login_date
    FROM (
        SELECT DISTINCT user_id FROM user_login
    ) u
    LATERAL VIEW posexplode(
        split(repeat('1', DATEDIFF('2023-01-31', '2023-01-01')), '1')
    ) t AS pos, val
)
SELECT 
    ad.user_id,
    ad.login_date,
    COALESCE(ul.login_count, 0) AS login_count
FROM all_dates ad
LEFT JOIN (
    SELECT 
        user_id,
        login_date,
        COUNT(*) AS login_count
    FROM user_login
    GROUP BY user_id, login_date
) ul 
ON ad.user_id = ul.user_id AND ad.login_date = ul.login_date;

十、异常值检测(离群点识别)

核心思路
  1. 计算统计指标:如均值、标准差。
  2. 定义阈值:如 |值 - 均值| > 3*标准差
典型例题

找出订单金额异常高的记录。

代码模板
WITH order_stats AS (
    SELECT 
        AVG(amount) AS avg_amount,
        STDDEV(amount) AS std_amount
    FROM orders
)
SELECT 
    o.order_id,
    o.amount
FROM orders o
CROSS JOIN order_stats s
WHERE ABS(o.amount - s.avg_amount) > 3 * s.std_amount;

总结

  1. 明确业务需求:确定输入输出,如 “连续登录”“留存率”。
  2. 设计数据模型:分析涉及的表、关联字段和聚合维度。
  3. 选择技术方案:套用上述思路(如连续值用 日期-行号,Top N 用 ROW_NUMBER)。
  4. 分步实现:先写基础查询,再叠加窗口函数和优化逻辑。
  5. 验证结果:用小规模数据测试,检查边界条件(如空值、单条记录)。

网站公告

今日签到

点亮在社区的每一天
去签到