在 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
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
我有一个 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
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