在 Apache Doris 中,若需实现 “相邻数据间取上一条 / 下一条数据的字段值”,核心是利用 窗口函数(Window Function) 中的 LAG()
(取上一条)和 LEAD()
(取下一条)函数。这两个函数专门用于在有序的数据集内,获取当前行相邻行的指定字段值,无需手动关联表,效率更高。
场景 1:全表按日期排序,取每条数据的 “上日销售额” 和 “次日销售额”
SELECTsale_date, -- 当前日期region, -- 当前区域sales_amount, -- 当前销售额-- 取上一条(前1行)的销售额,无数据时返回0LAG(sales_amount, 1, 0) OVER (ORDER BY sale_date) AS prev_day_sales,-- 取下一条(后1行)的销售额,无数据时返回0LEAD(sales_amount, 1, 0) OVER (ORDER BY sale_date) AS next_day_sales FROM sales;
场景 2:按区域分组,同一区域内按日期排序取相邻销售额
若表中包含多区域数据,需确保 “相邻” 仅在同一区域内生效(如华北的 “上一条” 不能是华东的数据),需添加 PARTITION BY region
:
SELECTsale_date,region,sales_amount,-- 按区域分组,组内按日期排序,取上日销售额LAG(sales_amount, 1, 0) OVER (PARTITION BY region ORDER BY sale_date) AS prev_day_sales_in_region,-- 按区域分组,组内按日期排序,取次日销售额LEAD(sales_amount, 1, 0) OVER (PARTITION BY region ORDER BY sale_date) AS next_day_sales_in_region FROM sales;
场景 3:取 “上两条” 或 “下两条” 数据
若需跨多行获取相邻值(如取 “上两日销售额”),只需调整 offset
参数为 2
:
SELECTsale_date,sales_amount,-- 取上两条(前2行)的销售额,无数据时返回NULLLAG(sales_amount, 2, NULL) OVER (ORDER BY sale_date) AS prev_2day_sales,-- 取下两条(后2行)的销售额,无数据时返回NULLLEAD(sales_amount, 2, NULL) OVER (ORDER BY sale_date) AS next_2day_sales FROM sales;
注意事项:
1、ORDER BY 必须指定:Doris 表的物理存储是无序的,若未在 OVER 子句中添加 ORDER BY,“相邻” 的定义不明确,函数会返回随机结果,导致逻辑错误。
2、PARTITION BY 按需使用:若业务需要 “分组内相邻”(如同一用户、同一区域),必须添加 PARTITION BY;若需全表相邻,则省略。
3、默认值与字段类型匹配:default_val 的类型需与 col_name 一致(如数值型字段默认值用 0,字符串用 '',日期用 '1970-01-01'),否则会报错。
4、性能优化:若表数据量较大,建议对 PARTITION BY 和 ORDER BY 涉及的字段创建 复合排序键(Sorted Key),减少窗口函数的计算开销(Doris 的 OLAP 引擎对有序数据的窗口计算更高效)。
通过 LAG()
和 LEAD()
函数,可轻松实现 Doris 中相邻数据的字段值获取,满足 “环比分析”“前后状态对比” 等常见业务需求。