2016-10-08 7 views
0
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 

質問: 上記のクエリでは、なぜDT2ではなくDT1でNullが取得されているのか理解できません。ここでは、Order by Clauseの解析関数MAXにどのような影響がありますか?解析機能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 
+0

どのような結果が得られますか? –

+0

DT \t \t \t \t || DT1 \t \t \t \t || A \t || D \t \t \t \t || C \t || E NULL \t \t \t || 2014年10月4日0:03 \t || 9 \t || 10/8/2016 0:03 \t || 1 \t || 1 NULL \t \t \t || 2014年10月4日0:03 \t || 3 \t || 2016年10月7日0:03 \t || 1 \t || 1 NULL \t \t \t || 2014年10月4日0:03 \t || 2 \t || 10/6/2016 0:03 \t || 6 \t || 1 10/4/2016 0:03 \t || 2014年10月4日0:03 \t || 5 \t || 2014年10月4日0:03 \t || 2 \t || 1 10/4/2016 0:03 \t || 2014年10月4日0:03 \t || 1 \t || 10/3/2016 0:03 \t || 2 \t || 1 – KrGk

答えて

0

あなたは(標準SQLに基づく)RANGE UNBOUNDED PRECEDINGのウィンドウ定義に分析関数のそれはデフォルト内ORDER BYを指定:この

結果を理解する助けてください。

これは、暗黙のデフォルトウィンドウを使用してクエリです:

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より道効率が低いです。

+0

@krgk - dnoethの答えをさらに説明するために、DT2では 'max()'がパーティション全体に渡っています( 'partition by'の後に 'order by'句がない場合の動作)。しかし、DT1では、 'c = 2 'の行が最後に来る(' d descによって順序付けされ、 'c = 2'で最も古い日付がある行のために)。このため、実行中(現在のパーティションの最初の行から現在の行まで)に適用された 'max(case ...)'は、 'max()'をヌルだけに渡し、 2行 – mathguy

+0

'range'と' rows'についてのポイントについては、現在のように結びつきがある場合、 'range'と' rows'は論理的に意味が異なるので、問題の要件に基づいて選択する必要があります。効率ではありません。 – mathguy

+0

@mathguy:もちろん、ORDER BYが一意でない限り、RANGEとROWSには違いがありますが、これはわかっています。明示的に書くときは、少なくともそれを知っておくべきです:) – dnoeth