Аналитическая функция MAX Проблемы

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

Вопрос: В приведенном выше запросе я не могу понять, почему я получаю Null в 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

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Вот почему существует общая рекомендация всегда добавлять определение окна, а не полагаться на значения по умолчанию.

Другие вопросы по тегам