SQL - 使用 LEAD 跳过具有特定条件的行

SQL - Using LEAD to skip over rows with a certain condition

在 Google BigQuery 中使用标准 SQL。

我有一个 table 有 2 种订单类型:A 和 B。

Id | Type | OrderDate
-----------------
1  |  A   | 2019-03-01
2  |  B   | 2019-03-04
3  |  B   | 2019-03-04
4  |  A   | 2019-03-05
5  |  A   | 2019-03-06
6  |  B   | 2019-04-05

对于每个订单类型 A,我想计算出下一个订单 B 的时间,忽略所有其他订单 A。

所以在我的示例数据中,如果我想 return 以下内容:

Id | Type | NextOrderBDate
--------------------------------
1  |  A   | 2019-03-04
4  |  A   | 2019-04-05
5  |  A   | 2019-04-05

我确实通过将 A 和 B 的 2 个单独的 table 相互连接来实现极其低效的结果 - 但是数据集非常大,运行 花了一个多小时。

我目前正在尝试做的是像这样使用 LEAD 语句:

SELECT Id, Type,
    LEAD(OrderDate) OVER (PARTITION BY Id ORDER BY OrderDate)
FROM xxx

显然这里的问题是它将 return 下一个日期,无论订单类型如何。

我想知道这样做的关键是否是计算出每一行需要导致下一个 B 型订单的正确偏移量,并且我正在努力在这里找到一个(干净的)解决方案。

提前致谢。

您可以按如下方式使用内联查询:

select
    id,
    type,
    (
        select min(OrderDate) 
        from mytable t1 
        where t1.Type = 'B' and t1.OrderDate >= t.OrderDate
    ) NextOrderBDate
from mytable t
where type = 'A'

Demo on DB Fiddlde:

id | type | NextOrderBDate
-: | :--- | :-------------
 1 | A    | 2019-03-04    
 4 | A    | 2019-04-05    
 5 | A    | 2019-04-05    

只需使用累计最小值:

select t.*
from (select t.*,
             min(case when type = 'B' then orderdate end) over (order by orderdate) as next_b_orderdate
      from t
     ) t
where type = 'A';

@Gordon Linoff 是对的,除了小错误:应该找到与每个当前订单相关的下一个 B 订单。因此 window 查询应该适当地调整恕我直言:

with t (id, type, orderdate) as (
  select 1  ,  'A'   , date '2019-03-01' union
  select 2  ,  'B'   , date '2019-03-04' union
  select 3  ,  'B'   , date '2019-03-04' union
  select 4  ,  'A'   , date '2019-03-05' union
  select 5  ,  'A'   , date '2019-03-06' union
  select 6  ,  'B'   , date '2019-04-05'
)
select t.*
from (select t.*,
             min(case when type = 'B' then orderdate end)
             over (order by orderdate 
                 rows between current row and unbounded following
             ) as next_b_orderdate
      from t
     ) t
where type = 'A';