点击上方【蓝色】字体 关注我们

01 场景描述

02 数据准备
-- 创建表CREATE TABLE employees (employee_id INT,row_number INT,column_number INT);-- 插入示例数据INSERT INTO employees VALUES(1, 1, 1),(2, 1, 2),(3, 1, 3),(4, 2, 1),(5, 2, 2),(6, 2, 3),(7, 3, 1),(8, 3, 2),(9, 3, 3);

03 问题分析
步骤一:使用分析函数计算每个员工与其他员工在行号和列号上的差值
我们要找出相邻座位的员工,首先需要计算每个员工与其他员工在座位行号和列号上的差值,通过分析函数来实现这一操作,方便后续判断相邻关系。
-- 使用分析函数计算行号和列号差值SELECTe1.employee_id AS employee_id_1,e2.employee_id AS employee_id_2,e1.row_number - e2.row_number AS row_diff,e1.column_number - e2.column_number AS col_diffFROM employees e1JOIN employees e2 ON e1.employee_id!= e2.employee_idORDER BY e1.employee_id, e2.employee_id;

-- 判断相邻关系并筛选出相邻座位的员工SELECTemployee_id_1,employee_id_2FROM (SELECTe1.employee_id AS employee_id_1,e2.employee_id AS employee_id_2,e1.row_number - e2.row_number AS row_diff,e1.column_number - e2.column_number AS col_diffFROM employees e1JOIN employees e2 ON e1.employee_id!= e2.employee_id) subqueryWHERE (ABS(row_diff) = 1 AND col_diff = 0) OR (row_diff = 0 AND ABS(col_diff) = 1);

04 小 结
窗口函数分析法(另一种解法):
**利用窗口函数和条件判断(另一种窗口函数用法)**- **思路**:- 可以先使用窗口函数来计算每个员工的上下左右四个方向的员工ID(如果存在)。然后,通过筛选这些计算结果来找出相邻座位的员工。- **示例代码**:```sql-- 使用窗口函数找出相邻座位的员工(同行相邻列和同列相邻行情况)select employee_id_1, value employe_id_2from (SELECT employee_id_1, concat_ws(',', cast(left_adjacent as string), cast(right_adjacent as string), cast(up_adjacent as string),cast(down_adjacent as string)) employee_id_2FROM (-- 利用窗口函数计算相邻座位相关信息SELECT e.employee_id AS employee_id_1,-- 同行左边相邻员工ID(如果有)LAG(e.employee_id, 1)OVER (PARTITION BY e.row_number ORDER BY e.column_number) AS left_adjacent,-- 同行右边相邻员工ID(如果有)LEAD(e.employee_id, 1)OVER (PARTITION BY e.row_number ORDER BY e.column_number) AS right_adjacent,-- 同列上边相邻员工ID(如果有)LAG(e.employee_id, 1)OVER (PARTITION BY e.column_number ORDER BY e.row_number) AS up_adjacent,-- 同列下边相邻员工ID(如果有)LEAD(e.employee_id, 1)OVER (PARTITION BY e.column_number ORDER BY e.row_number) AS down_adjacentFROM employees e) subqueryWHERE coalesce(left_adjacent, right_adjacent, up_adjacent, down_adjacent) is not null) tlateral view explode(split(employee_id_2,',')) tmp as value


第二步:行列转换
SELECT employee_id_1, concat_ws(',', cast(left_adjacent as string), cast(right_adjacent as string), cast(up_adjacent as string),cast(down_adjacent as string)) employee_id_2FROM (-- 利用窗口函数计算相邻座位相关信息SELECT e.employee_id AS employee_id_1,-- 同行左边相邻员工ID(如果有)LAG(e.employee_id, 1)OVER (PARTITION BY e.row_number ORDER BY e.column_number) AS left_adjacent,-- 同行右边相邻员工ID(如果有)LEAD(e.employee_id, 1)OVER (PARTITION BY e.row_number ORDER BY e.column_number) AS right_adjacent,-- 同列上边相邻员工ID(如果有)LAG(e.employee_id, 1)OVER (PARTITION BY e.column_number ORDER BY e.row_number) AS up_adjacent,-- 同列下边相邻员工ID(如果有)LEAD(e.employee_id, 1)OVER (PARTITION BY e.column_number ORDER BY e.row_number) AS down_adjacentFROM employees e) subqueryWHERE coalesce(left_adjacent, right_adjacent, up_adjacent, down_adjacent) is not null

第一步: 核心逻辑
-- 利用窗口函数计算相邻座位相关信息SELECT e.employee_id AS employee_id_1,-- 同行左边相邻员工ID(如果有)LAG(e.employee_id, 1)OVER (PARTITION BY e.row_number ORDER BY e.column_number) AS left_adjacent,-- 同行右边相邻员工ID(如果有)LEAD(e.employee_id, 1)OVER (PARTITION BY e.row_number ORDER BY e.column_number) AS right_adjacent,-- 同列上边相邻员工ID(如果有)LAG(e.employee_id, 1)OVER (PARTITION BY e.column_number ORDER BY e.row_number) AS up_adjacent,-- 同列下边相邻员工ID(如果有)LEAD(e.employee_id, 1)OVER (PARTITION BY e.column_number ORDER BY e.row_number) AS down_adjacentFROM employees e;


往期精彩
SQL进阶技巧:如何根据座位距离查找员工?| 员工座位安排问题
SQL进阶技巧:如何查找每个部门里坐在角落位置的员工?| 员工座位安排问题
解锁SQL无限可能:如何利用HiveSQL实现0-1背包问题?
会飞的一十六
扫描右侧二维码关注我们
点个【在看】 你最好看

文章转载自会飞的一十六,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。






