当前位置: 首页 > news >正文

大数据学习(138)-Hive数据分析3

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

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


一、分组排序问题(Top N 变体)

1. 按多个条件排序并取 Top N

问题:查询每个部门薪资最高且入职最早的前 2 名员工。
思路

  • 窗口函数中用 ORDER BY salary DESC, hire_date ASC 实现多条件排序。
  • 用 ROW_NUMBER() 生成唯一排名,避免并列。

代码模板

WITH ranked_employees AS (SELECT *,ROW_NUMBER() OVER (PARTITION BY dept_id ORDER BY salary DESC, hire_date ASC) AS rankFROM employees
)
SELECT * FROM ranked_employees WHERE rank <= 2;
2. 动态 Top N(按分组比例取前 N%)

问题:查询每个部门薪资前 10% 的员工。
思路

  • 用 NTILE(10) 将数据按薪资分为 10 组,取第 1 组。

代码模板

WITH salary_tiles AS (SELECT *,NTILE(10) OVER (PARTITION BY dept_id ORDER BY salary DESC) AS salary_tileFROM employees
)
SELECT * FROM salary_tiles WHERE salary_tile = 1;

二、连续区间问题(变体)

1. 连续缺失值检测

问题:检测用户登录记录中连续缺失超过 3 天的区间。
思路

  • 生成完整日期序列,左连接实际记录,标记缺失日期。
  • 用 日期-行号 分组连续缺失区间。

代码模板

WITH all_dates AS (-- 生成日期序列(略)
),
missing_dates AS (SELECT user_id,date,CASE WHEN login_id IS NULL THEN 1 ELSE 0 END AS is_missingFROM all_datesLEFT JOIN user_logins USING (user_id, date)
),
missing_groups AS (SELECT user_id,date,DATE_SUB(date, ROW_NUMBER() OVER (PARTITION BY user_id, is_missing ORDER BY date)) AS grpFROM missing_datesWHERE is_missing = 1
)
SELECT user_id,MIN(date) AS start_date,MAX(date) AS end_date,COUNT(*) AS missing_days
FROM missing_groups
GROUP BY user_id, grp
HAVING COUNT(*) > 3;
2. 周期性行为识别

问题:识别用户每周固定某天的登录习惯(如每周三)。
思路

  • 用 DAYOFWEEK() 获取星期几,按用户和星期分组统计频次。

代码模板

SELECT user_id,DAYOFWEEK(login_date) AS day_of_week,COUNT(*) AS login_count,ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY COUNT(*) DESC) AS rank
FROM user_logins
GROUP BY user_id, DAYOFWEEK(login_date)
HAVING rank = 1;  -- 取频次最高的一天

三、复杂聚合问题

1. 分组内条件聚合(加权平均)

问题:计算每个商品在不同促销活动下的加权平均销量(权重为活动持续天数)。
思路

  • 用 SUM(销量*权重)/SUM(权重) 实现加权平均。

代码模板

SELECT product_id,SUM(sales * duration_days) / SUM(duration_days) AS weighted_avg_sales
FROM (SELECT product_id,campaign_id,SUM(daily_sales) AS sales,DATEDIFF(end_date, start_date) + 1 AS duration_daysFROM sales_recordsGROUP BY product_id, campaign_id, start_date, end_date
) t
GROUP BY product_id;
2. 动态区间聚合(按事件触发)

问题:计算用户每次登录后 24 小时内的消费总额。
思路

  • 用 JOIN 关联同一用户的登录和消费记录,筛选时间窗口。

代码模板

SELECT l.user_id,l.login_time,SUM(o.amount) AS total_spent
FROM user_logins l
LEFT JOIN orders o 
ON l.user_id = o.user_id 
AND o.order_time BETWEEN l.login_time AND DATE_ADD(l.login_time, 1)
GROUP BY l.user_id, l.login_time;

四、多维分析(OLAP 风格)

1. 小计与总计(GROUPING SETS/CUBE/ROLLUP)

问题:同时计算按部门、职位和两者组合的薪资总和。
思路

  • 用 GROUPING SETS 生成多种分组组合。

代码模板

SELECT dept_id,position,SUM(salary) AS total_salary
FROM employees
GROUP BY GROUPING SETS((dept_id, position),  -- 部门+职位分组(dept_id),            -- 部门分组(position),           -- 职位分组()                    -- 总计
);
2. 同比 / 环比(跨时间周期比较)

问题:计算 2023 年每月销售额的同比和环比增长率。
思路

  • 用 LAG() 获取上月 / 去年同月数据,或用 JOIN 关联时间偏移表。

代码模板

WITH monthly_sales AS (SELECT YEAR(sale_date) AS sale_year,MONTH(sale_date) AS sale_month,SUM(amount) AS total_amountFROM salesGROUP BY YEAR(sale_date), MONTH(sale_date)
)
SELECT curr.sale_year,curr.sale_month,curr.total_amount,prev_month.total_amount AS prev_month_amount,prev_year.total_amount AS prev_year_amount,(curr.total_amount - prev_month.total_amount) / prev_month.total_amount AS mom_growth,(curr.total_amount - prev_year.total_amount) / prev_year.total_amount AS yoy_growth
FROM monthly_sales curr
LEFT JOIN monthly_sales prev_month 
ON curr.sale_year = prev_month.sale_year 
AND curr.sale_month = prev_month.sale_month + 1
LEFT JOIN monthly_sales prev_year 
ON curr.sale_year = prev_year.sale_year + 1 
AND curr.sale_month = prev_year.sale_month;

五、地理信息与空间分析

1. 区域聚合(按地理边界统计)

问题:统计每个城市商圈内的店铺数量。
思路

  • 用 ST_Contains() 判断点(店铺)是否在多边形(商圈)内。

代码模板

SELECT district_name,COUNT(shop_id) AS shop_count
FROM shops s
JOIN districts d 
ON ST_Contains(ST_GeomFromText(d.polygon_wkt),  -- 商圈多边形ST_Point(s.longitude, s.latitude)  -- 店铺坐标
)
GROUP BY district_name;
2. 距离最近点查询

问题:为每个用户找到距离最近的 3 个服务点。
思路

  • 用 Haversine 公式计算距离,ROW_NUMBER() 取 Top N。

代码模板

WITH distances AS (SELECT u.user_id,s.service_id,6371 * 2 * ASIN(SQRT(POWER(SIN((s.lat - u.lat) * PI()/180 / 2), 2) +COS(u.lat * PI()/180) * COS(s.lat * PI()/180) *POWER(SIN((s.lon - u.lon) * PI()/180 / 2), 2))) AS distance_kmFROM users uCROSS JOIN service_points s
)
SELECT *
FROM (SELECT *,ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY distance_km) AS rankFROM distances
) t
WHERE rank <= 3;

六、时间窗口滑动聚合

1. 固定窗口聚合(每小时 / 每天)

问题:计算每小时的平均请求数。
思路

  • 用 DATE_TRUNC() 截断时间到小时,按小时分组。

代码模板

SELECT DATE_TRUNC('HOUR', request_time) AS hour,COUNT(request_id) AS request_count,AVG(response_time) AS avg_response_time
FROM requests
GROUP BY DATE_TRUNC('HOUR', request_time);
2. 滑动窗口聚合(过去 N 条记录)

问题:计算每个用户最近 5 次登录的平均停留时长。
思路

  • 用 ROWS BETWEEN 4 PRECEDING AND CURRENT ROW 定义滑动窗口。

代码模板

SELECT user_id,login_time,session_duration,AVG(session_duration) OVER (PARTITION BY user_id ORDER BY login_time ROWS BETWEEN 4 PRECEDING AND CURRENT ROW) AS avg_last_5_sessions
FROM user_sessions;

七、数据透视与交叉表

1. 动态列转置(不确定列数)

问题:将用户标签(每行一个标签)转为列(每个标签一列)。
思路

  • 用 collect_set() 聚合标签,size() 判断是否存在。

代码模板

WITH user_tags AS (SELECT user_id,collect_set(tag) AS tagsFROM user_tag_mappingGROUP BY user_id
)
SELECT user_id,CASE WHEN 'vip' IN (SELECT * FROM UNNEST(tags)) THEN 1 ELSE 0 END AS is_vip,CASE WHEN 'new' IN (SELECT * FROM UNNEST(tags)) THEN 1 ELSE 0 END AS is_new,-- 动态添加更多标签判断
FROM user_tags;
2. 交叉表统计(多维度组合)

问题:统计不同年龄段和性别用户的消费金额分布。
思路

  • 用 CASE WHEN 组合维度,SUM() 聚合金额。

代码模板

SELECT age_group,SUM(CASE WHEN gender = 'M' THEN amount ELSE 0 END) AS male_amount,SUM(CASE WHEN gender = 'F' THEN amount ELSE 0 END) AS female_amount,SUM(amount) AS total_amount
FROM users u
JOIN orders o USING (user_id)
GROUP BY age_group;

八、递归查询与层级结构

1. 树形结构路径查询(如组织架构)

问题:查询员工及其所有上级的完整路径。
思路

  • 用递归 CTE 逐层向上查找上级。

代码模板

WITH RECURSIVE employee_hierarchy AS (SELECT emp_id,manager_id,emp_name,CAST(emp_name AS STRING) AS pathFROM employeesWHERE manager_id IS NULL  -- 根节点(CEO)UNION ALLSELECT e.emp_id,e.manager_id,e.emp_name,CONCAT(eh.path, ' -> ', e.emp_name) AS pathFROM employees eJOIN employee_hierarchy eh ON e.manager_id = eh.emp_id
)
SELECT * FROM employee_hierarchy;
2. 层级聚合(如区域销售额汇总)

问题:计算每个区域及其子区域的总销售额。
思路

  • 自下而上递归聚合,用 SUM() OVER (PARTITION BY region_id)

代码模板

WITH region_sales AS (-- 基础销售额(略)
),
region_hierarchy AS (-- 区域层级关系(略)
),
recursive_sales AS (-- 递归计算子区域销售额(略)
)
SELECT region_id,region_name,SUM(sales_amount) OVER (PARTITION BY region_id) AS total_sales
FROM recursive_sales;

九、字符串与模式匹配

1. 复杂字符串分割与提取

问题:从日志中提取 user_id 和 action(格式:[user_id:1001][action:click])。
思路

  • 用 regexp_extract() 或 substr()+instr() 提取子串。

代码模板

SELECT regexp_extract(log_line, '\\[user_id:(\\d+)\\]', 1) AS user_id,regexp_extract(log_line, '\\[action:(\\w+)\\]', 1) AS action
FROM logs;
2. 字符串相似度计算

问题:找出商品名称中包含特定关键词的记录。
思路

  • 用 LIKE 或 REGEXP 匹配,或用 levenshtein_distance() 计算编辑距离。

代码模板

-- 方法1:模糊匹配
SELECT * FROM products WHERE product_name LIKE '%关键词%';-- 方法2:正则匹配
SELECT * FROM products WHERE product_name REGEXP '关键词';-- 方法3:相似度计算
SELECT * 
FROM products 
WHERE levenshtein_distance(product_name, '目标名称') <= 3;

解题思路:

  1. 问题拆解:将复杂需求分解为子问题(如 “连续登录” → “生成连续标识” → “分组统计”)。
  2. 数据建模:明确输入输出表结构,确定关联字段和聚合维度。
  3. 技术选型
    • 窗口函数:排名、累计计算、滑动窗口。
    • JOIN:关联多表数据,注意过滤条件前置。
    • 正则 / JSON 函数:处理复杂字符串和嵌套结构。
  4. 性能优化
    • 用 EXPLAIN 分析执行计划,避免全表扫描。
    • 对大表 JOIN 考虑 MapJoin 或分桶表。
    • 过滤条件尽量前置,减少中间数据量。

相关文章:

  • 部署http服务
  • 2025-06-13【api】阿里百炼api调用方法
  • Windows 提权工具(“Potato“ 系列)用法指南
  • 基于51单片机的温室植物生长环境监测系统
  • WPF将容器内的组件按比例缩放
  • Linux中shell编程的函数递归用法和脚本自动化讲解
  • Redis : set集合
  • wpf 解决DataGridTemplateColumn中width绑定失效问题
  • GaussDB创建数据库存储
  • Tomcat调优
  • Linux Alias 魔法:命令行效率提升秘籍
  • docker-Dockerfile 配置
  • 晶圆搬运机器人与RFID半导体读卡器携手赋能半导体制造高效变革
  • CentOS变Ubuntu后后端程序SO库报错,解决方案+原理分析!
  • centos 7.9 升级ssh版本 7.4p1 升级到 8.2p1
  • centos转移mysql的数据存储目录
  • 快速排序:分治思想的经典实践
  • 【Linux系统编程】进程信号 - 信号产生
  • 3分钟入门深度学习(迷你级小项目): XOR 门神经网络训练与测试简明教程
  • 【Docker管理工具】安装容器管理工具Oxker
  • 佛山怎么做网站/怎样建网站赚钱
  • 做网站如何避免商标侵权/免费打广告网站
  • 网站如何备案icp备案/国内免费建网站
  • 通过云主机建设网站/友链互换平台推荐
  • 给别人做网站赚钱/优云优客百度推广效果怎么样
  • 工程机械网站设计/电商运营工资一般多少钱一个月