在分析函数中过滤行 - Oracle

Posted

技术标签:

【中文标题】在分析函数中过滤行 - Oracle【英文标题】:Filter rows within an analytical function - Oracle 【发布时间】:2019-12-09 11:22:03 【问题描述】:

我需要过滤分析函数中的行(例如:滞后)。 有没有办法有效地做到这一点没有子查询(这是一个非常大的表)?

这是桌子:

预期的结果应该如下所示:

【问题讨论】:

请显示您的查询使用解析函数 样本数据最好显示为formatted text。请参阅here,了解有关如何创建漂亮表格的一些提示。 【参考方案1】:

这看起来像是分析函数的典型用法。在这种情况下,我认为累积的max() 似乎是合适的:

select t.*,
       max(case when is_valid = 1 then date end) over 
           (partition by client_id
            order by date
            rows between unbounded preceding and 1 preceding
           ) as last_valid_session
from t;

很难想出更简洁的方式来实现这个逻辑,尽管lag()last_value() 也可以使用:

select t.*,
       lag(case when is_valid = 1 then date end ignore nulls) over 
           (partition by client_id
            order by date
           ) as last_valid_session
from t;

【讨论】:

【参考方案2】:

LAGIGNORE NULLSCASE 表达式一起使用以仅过滤有效日期:

Oracle 设置

CREATE TABLE test_data ( session_id, client_id, is_valid, "DATE" ) AS
SELECT  1, 11, 0, DATE '2018-01-01' FROM DUAL UNION ALL
SELECT  2, 22, 1, DATE '2018-01-02' FROM DUAL UNION ALL
SELECT  3, 33, 0, DATE '2018-01-03' FROM DUAL UNION ALL
SELECT  4, 11, 1, DATE '2018-01-04' FROM DUAL UNION ALL
SELECT  5, 22, 0, DATE '2018-01-05' FROM DUAL UNION ALL
SELECT  6, 33, 1, DATE '2018-01-06' FROM DUAL UNION ALL
SELECT  7, 11, 0, DATE '2018-01-07' FROM DUAL UNION ALL
SELECT  8, 22, 1, DATE '2018-01-08' FROM DUAL UNION ALL
SELECT  9, 33, 0, DATE '2018-01-09' FROM DUAL UNION ALL
SELECT 10, 11, 1, DATE '2018-01-10' FROM DUAL;

查询

SELECT t.*,
       LAG( CASE is_valid WHEN 1 THEN "DATE" END )
         IGNORE NULLS
         OVER ( PARTITION BY client_id ORDER BY "DATE" )
         AS last_valid_session
FROM   test_data t
ORDER BY session_id

输出

会话 ID |客户 ID | IS_VALID |日期 | LAST_VALID_SESSION ---------: | --------: | --------: | :-------- | :----------------- 1 | 11 | 0 | 2018 年 1 月 1 日 | 2 | 22 | 1 | 2018 年 1 月 2 日 | 3 | 33 | 0 | 2018 年 1 月 3 日 | 4 | 11 | 1 | 2018 年 1 月 4 日 | 5 | 22 | 0 | 2018 年 1 月 5 日 | 2018 年 1 月 2 日 6 | 33 | 1 | 2018 年 1 月 6 日 | 7 | 11 | 0 | 2018 年 1 月 7 日 | 2018 年 1 月 4 日 8 | 22 | 1 | 2018 年 1 月 8 日 | 2018 年 1 月 2 日 9 | 33 | 0 | 2018 年 1 月 9 日 | 2018 年 1 月 6 日 10 | 11 | 1 | 18 年 1 月 10 日 | 2018 年 1 月 4 日

db小提琴here

【讨论】:

以上是关于在分析函数中过滤行 - Oracle的主要内容,如果未能解决你的问题,请参考以下文章

Oracle分析函数之Lag和Lead()使用

学习Oracle分析函数

学习Oracle分析函数(Analytic Functions)

ORACLE 偏移分析函数 lag()与lead() 用法

ORACLE 偏移分析函数 lag()与lead() 用法

求 Oracle 分析函数