【问题标题】:Analytic Function MAX Issues解析函数 MAX 问题
【发布时间】:2016-10-08 08:09:55
【问题描述】:
WITH t AS (
    SELECT 9 a
        ,sysdate d
        ,1 c
        ,1 e
    FROM dual       
    UNION       
    SELECT 1 a
        ,sysdate - 5 d
        ,2 c
        ,1 e
    FROM dual       
    UNION       
    SELECT 2 a
        ,sysdate - 2 d
        ,6 c
        ,1 e
    FROM dual       
    UNION       
    SELECT 5 a
        ,sysdate - 4 d
        ,2 c
        ,1 e
    FROM dual       
    UNION       
    SELECT 3 a
        ,sysdate - 1 d
        ,1 c
        ,1 e
    FROM dual       )
SELECT MAX(CASE 
            WHEN c = 2
                THEN d
            ELSE NULL
            END) OVER (
        PARTITION BY e ORDER BY d DESC          ) DT1
    ,MAX(CASE 
            WHEN c = 2
                THEN d
            ELSE NULL
            END) OVER (PARTITION BY e) DT2
    ,t.*
FROM t

问题: 在上面的查询中,我无法理解为什么在 DT1 中得到空值,而在 DT2 中没有。 Order By Clause 在解析函数 MAX 中的影响是什么?请帮助我理解这一点

结果:

DT             || DT1            || A || D              || C    || E 
NULL           || 10/4/2016 0:03 || 9 || 10/8/2016 0:03 || 1    || 1 
NULL           || 10/4/2016 0:03 || 3 || 10/7/2016 0:03 || 1    || 1 
NULL           || 10/4/2016 0:03 || 2 || 10/6/2016 0:03 || 6    || 1
10/4/2016 0:03 || 10/4/2016 0:03 || 5 || 10/4/2016 0:03 || 2    || 1 
10/4/2016 0:03 || 10/4/2016 0:03 || 1 || 10/3/2016 0:03 || 2    || 1

【问题讨论】:

  • 你得到什么结果?
  • DT || DT1 ||一个 || D || C || E 空值 || 2016 年 10 月 4 日 0:03 || 9 || 2016 年 10 月 8 日 0:03 || 1 || 1 空 || 2016 年 10 月 4 日 0:03 || 3 || 2016 年 10 月 7 日 0:03 || 1 || 1 空 || 2016 年 10 月 4 日 0:03 || 2 || 2016 年 10 月 6 日 0:03 || 6 || 1 2016 年 10 月 4 日 0:03 || 2016 年 10 月 4 日 0:03 || 5 || 2016 年 10 月 4 日 0:03 || 2 || 1 2016 年 10 月 4 日 0:03 || 2016 年 10 月 4 日 0:03 || 1 || 2016 年 10 月 3 日 0:03 || 2 || 1

标签: sql oracle max analytic-functions


【解决方案1】:

当您在分析函数中指定ORDER BY 时,它默认为RANGE UNBOUNDED PRECEDING 的窗口定义(基于标准SQL)。

这是您使用隐式默认窗口的查询:

SELECT Max(CASE 
            WHEN c = 2
                THEN d
            ELSE NULL
            END) Over (
        PARTITION BY e ORDER BY d DESC Range Unbounded Preceding
        ) DT1
    ,Max(CASE 
            WHEN c = 2
                THEN d
            ELSE NULL
            END) Over (PARTITION BY e range between unbounded preceding and unbounded following) DT2
    ,t.*
FROM t

顺便说一句,另外RANGE 的效率远低于ROWS,这就是为什么有一个常见的建议是始终添加窗口定义而不是依赖默认值。

【讨论】:

  • @krgk - 进一步解释 dnoeth 的答案:在 DT2 中,max() 覆盖整个分区(这就是它在partition by 之后没有order by 子句的工作方式)。但是,在 DT1 中,带有 c=2 的行排在最后(因为 order by d desc 和带有 c=2 的行具有最旧的日期)。出于这个原因,max(case...),在“运行”的基础上应用(从当前分区中的第一行到当前行)仅在空值上使用max(),直到它到达最后两行。
  • 关于rangerows这一点:像现在这样的情况,可能有联系,rangerows逻辑含义不同,所以选择应该基于问题的要求,而不是效率。
  • @mathguy:你是对的,RANGE 和 ROWS 之间当然存在差异(除非 ORDER BY 是唯一的),我认为这是已知的。至少当你明确写它时你应该知道它:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-26
  • 1970-01-01
  • 1970-01-01
  • 2011-10-29
  • 2021-08-01
  • 2013-12-14
  • 2018-04-06
相关资源
最近更新 更多