You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用BigQuery SQL获取下一组订单起始日期

问题描述

现有如下结构的订单详情表:

Order Id    Order_start_date
O1          9/10/2022
O1          9/10/2022
O1          9/12/2023
O1          9/12/2023
O1          9/14/2023
O1          9/14/2023

需要新增Next_Order_start_date字段,代表当前订单日期组的下一组起始日期,期望结果如下:

Order_id    Order_start_date    Next_Order_start_date
O1          9/10/2022           9/12/2023
O1          9/10/2022           9/12/2023
O1          9/12/2023           9/14/2023
O1          9/12/2023           9/14/2023
O1          9/14/2023           Null
O1          9/14/2023           Null

创建该表的BigQuery SQL语句如下:

WITH  ORDER_DETAIL AS 
(
    SELECT 'O1' AS ORD_ID , DATE('2022-09-10') AS ORDER_START_DT
    UNION ALL 
    SELECT 'O1' AS ORD_ID , DATE('2022-09-10') AS ORDER_START_DT
    UNION ALL 
    SELECT 'O1' AS ORD_ID , DATE('2022-09-12')  AS ORDER_START_DT
    UNION ALL 
    SELECT 'O1' AS ORD_ID , DATE('2022-09-12')  AS ORDER_START_DT
    UNION ALL 
    SELECT 'O1' AS ORD_ID , DATE('2022-09-14') AS ORDER_START_DT
    UNION ALL 
    SELECT 'O1' AS ORD_ID , DATE('2022-09-14') AS ORDER_START_DT
)
SELECT ORD_ID, ORDER_START_DT
FROM ORDER_DETAIL

如何使用BigQuery SQL实现获取Next_order_start_dt字段?

解决方案

可以通过窗口函数结合分组去重的方式实现,核心思路是先识别每个订单下的唯一日期组,再为每个组匹配后续的日期。

方法1:先分组去重再关联(逻辑清晰版)

先提取每个订单的唯一日期,用LEAD()获取下一组日期,再关联回原始表为每条记录匹配对应值:

WITH  ORDER_DETAIL AS 
(
    SELECT 'O1' AS ORD_ID , DATE('2022-09-10') AS ORDER_START_DT
    UNION ALL 
    SELECT 'O1' AS ORD_ID , DATE('2022-09-10') AS ORDER_START_DT
    UNION ALL 
    SELECT 'O1' AS ORD_ID , DATE('2022-09-12')  AS ORDER_START_DT
    UNION ALL 
    SELECT 'O1' AS ORD_ID , DATE('2022-09-12')  AS ORDER_START_DT
    UNION ALL 
    SELECT 'O1' AS ORD_ID , DATE('2022-09-14') AS ORDER_START_DT
    UNION ALL 
    SELECT 'O1' AS ORD_ID , DATE('2022-09-14') AS ORDER_START_DT
),
DATE_GROUPS AS (
    SELECT 
        ORD_ID,
        ORDER_START_DT,
        -- 按订单分组、日期排序,获取下一组的起始日期
        LEAD(ORDER_START_DT) OVER (PARTITION BY ORD_ID ORDER BY ORDER_START_DT) AS NEXT_ORDER_START_DT
    FROM (
        -- 提取唯一的订单-日期组合
        SELECT DISTINCT ORD_ID, ORDER_START_DT
        FROM ORDER_DETAIL
    )
)
SELECT 
    od.ORD_ID,
    od.ORDER_START_DT,
    dg.NEXT_ORDER_START_DT
FROM ORDER_DETAIL od
JOIN DATE_GROUPS dg 
    ON od.ORD_ID = dg.ORD_ID 
    AND od.ORDER_START_DT = dg.ORDER_START_DT
ORDER BY od.ORDER_START_DT;

方法2:嵌套窗口函数(代码简洁版)

利用DENSE_RANK()为每个日期组分配排名,再基于排名用LEAD()获取对应下一个日期:

WITH  ORDER_DETAIL AS 
(
    SELECT 'O1' AS ORD_ID , DATE('2022-09-10') AS ORDER_START_DT
    UNION ALL 
    SELECT 'O1' AS ORD_ID , DATE('2022-09-10') AS ORDER_START_DT
    UNION ALL 
    SELECT 'O1' AS ORD_ID , DATE('2022-09-12')  AS ORDER_START_DT
    UNION ALL 
    SELECT 'O1' AS ORD_ID , DATE('2022-09-12')  AS ORDER_START_DT
    UNION ALL 
    SELECT 'O1' AS ORD_ID , DATE('2022-09-14') AS ORDER_START_DT
    UNION ALL 
    SELECT 'O1' AS ORD_ID , DATE('2022-09-14') AS ORDER_START_DT
)
SELECT 
    ORD_ID,
    ORDER_START_DT,
    -- 基于日期组的排名,获取下一组的起始日期
    LEAD(ORDER_START_DT) OVER (
        PARTITION BY ORD_ID 
        ORDER BY DENSE_RANK() OVER (PARTITION BY ORD_ID ORDER BY ORDER_START_DT)
    ) AS NEXT_ORDER_START_DT
FROM ORDER_DETAIL;

逻辑说明

  • LEAD()窗口函数用于获取当前行之后指定偏移量的行的值,这里默认偏移1,即下一个日期组的日期。
  • 方法1通过先去重减少计算量,再关联回原始表,适合数据量较大的场景;方法2直接在原始表上嵌套窗口函数,代码更紧凑。

内容的提问来源于stack exchange,提问作者D Mishra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 20:28:10