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'
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';
在 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'
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';