在 sql 中使用 LAG 跳过特定行

Skip specific rows using LAG in sql

我有一个 table 看起来像这样:

使用 SQL 中的 LAG 函数,我想仅对 star_date=end_date 的值执行 LAG,并获取过去的 start_date 记录start_date=end_date。 我的结尾 table 将有这样一个额外的专栏:

我希望我的问题很清楚,感谢任何帮助。

您可以为这些值分配一个组并使用:

select t.*,
       (case when start_date = end_date
             then lag(start_date) over (partition by (case when start_date = end_date then 1 else 0 end) order by start_date)
        end) as prev_eq_start_date
from t;

或者:

select t.*,
       (case when start_date = end_date
             then lag(start_date) over (partition by start_date = end_date order by start_date)
        end) as prev_eq_start_date
from t;

请注意,如果您的数据很大并且大多数行都有不同的日期,那么您可能会遇到资源问题。在这种情况下,一个额外的、未使用的 partition by 键可以提供帮助:

select t.*,
       (case when start_date = end_date
             then lag(start_date) over (partition by (case when start_date = end_date then 1 else 2 end), (case when start_date <> end_date then start_date end) order by start_date)
        end) as prev_eq_start_date
from t;

这对结果没有影响,但可以避免因具有不同值的行太多而导致的资源错误。

使用JOIN

SQL FIDDLE

SELECT T.*,T1.LAG_Result
FROM TABLE T LEFT JOIN 
(
   SELECT User_Id,LAG(start_date) OVER(ORDER BY start_date) LAG_Result
   FROM TABLE S 
   WHERE start_date = end_date
) T1 ON T.User_Id = T1.User_Id 

以下适用于 BigQuery 标准 SQL

#standardSQL
SELECT *, NULL AS lag_result
FROM `project.dataset.table` WHERE start_date != end_date
UNION ALL
SELECT *, LAG(start_date) OVER(ORDER BY start_date)
FROM `project.dataset.table` WHERE start_date = end_date

如果应用于您问题中的示例数据 - 结果是

Row user_id start_date  end_date    lag_result   
1   1       2019-01-01  2019-02-28  null     
2   3       2019-02-27  2019-02-28  null     
3   4       2019-08-04  2019-09-01  null     
4   2       2019-02-01  2019-02-01  null     
5   5       2019-08-07  2019-08-07  2019-02-01   
6   6       2019-08-27  2019-08-27  2019-08-07     

顺便说一句,如果您的 start_date 和 end_date 是 STRING 数据类型('27/02/2019')与 DATE 类型('2019-02-27' 因为它假设在上面的查询中) - 你应该使用下面的一个

#standardSQL
SELECT *, NULL AS lag_result
FROM `project.dataset.table` WHERE start_date != end_date
UNION ALL
SELECT *, LAG(start_date) OVER(ORDER BY PARSE_DATE('%d/%m/%Y', start_date))
FROM `project.dataset.table` WHERE start_date = end_date

结果

Row user_id start_date  end_date    lag_result   
1   1   01/01/2019      28/02/2019  null     
2   3   27/02/2019      28/02/2019  null     
3   4   04/08/2019      01/09/2019  null     
4   2   01/02/2019      01/02/2019  null     
5   5   07/08/2019      07/08/2019  01/02/2019   
6   6   27/08/2019      27/08/2019  07/08/2019