2009-08-04 4 views
2

クエリは以下の通りです:このFIRST_VALUEクエリで何が問題になっていますか?

with t 
as (
    select 450 id, null txt , 3488 id_usr from dual union all 
    select 449 , null  , 3488  from dual union all 
    select 79 , 'A'  , 3488  from dual union all 
    select 78 , 'X'  , 3488  from dual 
) 
select id 
    , txt 
    , id_usr 
    , first_value(txt ignore nulls) over (partition by id_usr order by id desc) first_one 
    from t 

とリターン:間違って何

ID TXT  ID_USR FIRST_ONE 
450   3488 A 
449   3488 A 
79 A  3488 A 
78 X  3488 A 

と理由:

ID TXT  D_USR FIRST_ONE 
450   3488  
449   3488  
79 A  3488 A 
78 X  3488 A 

これが予想されていましたか?

答えて

5

FIRST_VALUEのデフォルトRANGE/ROWS(その他の分析機能の場合)はBETWEEN UNBOUNDED PRECEDING AND CURRENT ROWです。

IGNORE NULLSを追加すると、範囲を構築するときに値NULLが考慮されません。

RANGEBETWEEEN UNBOUNDED PRECEDING AND CURRENT ROW EXCEPT FOR THE NULL ROWSとなります(有効なOVER句ではありません)。 S、彼らが最初に選択し、その範囲が空になっているあなたのtxt「がNULLが高いidを持っているS」の以来

、何の非NULL行がそれらとUNBOUNDED PRECEDING

の間ではありませんので、あなたはどちらかORDER BYを変更する必要がありますクエリのRANGE句。非NULL値が(もしあれば)は、常に最初に選択されるようにORDER BY変更

は、ウィンドウの端にNULL IDが持つ行を置き、そしてRANGEはguaranteedlyその値から開始します:

with t 
as (
    select 450 id, null txt , 3488 id_usr from dual union all 
    select 449 , null  , 3488  from dual union all 
    select 79 , 'A'  , 3488  from dual union all 
    select 78 , 'X'  , 3488  from dual 
) 
select id 
    , txt 
    , id_usr 
    , first_value(txt) over (partition by id_usr order by NVL2(TXT, NULL, id) DESC) first_one 
    from t 

RANGEを変更すると、パーティション内のすべての非NULLの行が含まれるように範囲を再定義:

with t 
as (
    select 450 id, null txt , 3488 id_usr from dual union all 
    select 449 , null  , 3488  from dual union all 
    select 79 , 'A'  , 3488  from dual union all 
    select 78 , 'X'  , 3488  from dual 
) 
select id 
    , txt 
    , id_usr 
    , first_value(txt IGNORE NULLS) over (partition by id_usr order by id DESC RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) first_one 
    from t 
+0

あなたが「無視ヌル」節は思いとどまらせるためではないことを意味しますか最小値は「first_value」ですが、それはウィンドウ処理のためのものですか? – FerranB

+0

@FerranB:正確ではありません。 'id'でソートされた範囲から最初の非ヌル値を選択します。あなたの例で '450'を' 1'に置き換えると、 'A 'が選択されます。 – Quassnoi

+0

私はそれをよく言い返すでしょう、今混乱しています。 – Quassnoi

関連する問題