2017-01-30 17 views
0

これはまっすぐだと思われますが、わかりにくいです。私はグループ内のレコード(group_id)を比較しているテーブルを持っています。私は私の記録に、私の研究に関係する特定の基準に基づく旗を掲げました。私が見る必要がある約10のフラグがあります。グループ内では、1つのレコードのみがフラグされる場合もあります。それ以外の場合は、両方のレコードにフラグが立てられます。基準に基づいてグループ内で「パーティションバイ」を行うにはどうすればよいですか?

私が今したいのは、各フラグ指定の日付に基づいてgroup_idを分割することです。私は見たい3つの期間があります:2016年、2010年-2015年、2010年以前、両方の記録が同じです。これらは、日付型データとして設定されていない私の 'file_date'フィールドに反映されます。代わりに、彼らはabcsum(夏)とabcwin(冬)を指定しています。場合によっては、このフィールドはnullです。

私がしたいのは、パーティションの「勝者」がそれらの日付基準のどれに適合したかに基づいて別のフラグを作成することです。基準の重要性は、最新のものから最近のものまでです。ここで私はさらにそれを説明することを願っていますいくつかのサンプルデータは、次のとおりです。

------------------------------ 
|group_id | file_date | flag | 
------------------------------- 
| a  | abcsum16 | 3 | 
| a  | abcwin16 |  | 
| b  | null  | 4 | 
| b  | abcsum15 | 4 | 
| c  | abcwin16 | 7 | 
| c  | abcwin16 | 7 | 
| d  | abcsum09 | 3 | 
| d  | null  |  | 
------------------------------- 

出力は次のようになります。


|group_id | file_date | flag | date_flag | 
-------------------------------------------- 
| a  | abcsum16 | 3 | 1  | 
| b  | abcsum15 | 4 | 2  | 
| c  | abcwin16 | 7 | 0  | 
| c  | abcwin16 | 7 | 0  | 
| d  | abcsum09 | 3 | 3  | 
------------------------------------------- 
+0

これは不明です。どのようにしてdate_flagに値(0,1,2,3)を割り当てましたか? (2016年、2010年-2016年、そして2009年まで)3つの "クラス"がありますが、 "どちらのレコードも同じです"とはどういうことでしょうか?また、date_flagにはどのような影響がありますか?出力から? – mathguy

+0

残念ですが、日付フラグは次の通りです:1 = 2016年、2 = 2010年と2015年、3は2010年です;場合によっては、同じ 'file_date'の両方のレコードがあります。 2つの日付を区別することができないので、0を取るものです。なぜなら、私がnullフィールドを含まない理由は、それらを使うことができないからです、彼らがnullであることを示す異なるフラグコードをとることができると思います。 – user7002207

答えて

1

ここでそれを行うための1つの方法です。ただし、可能であれば、これらの手法をプロセスの早い段階で使用するほうがずっと良いことに注意してください。たとえば、file_dateが基本表にそのように格納されず、代わりに処理の結果である場合は、file_date式の代わりに基本データを使用する方がよいでしょう。また、分析関数をより早く使用して、データの通過回数を減らすこともできます(もちろん、パフォーマンスは重要であり、時にはそうでない場合もあります)。

with 
    test_data (group_id, file_date, flag) as (
     select 'a', 'abcsum16', 3 from dual union all 
     select 'a', 'abcwin16', null from dual union all 
     select 'b', null  , 4 from dual union all 
     select 'b', 'abcsum15', 4 from dual union all 
     select 'c', 'abcwin16', 7 from dual union all 
     select 'c', 'abcwin16', 7 from dual union all 
     select 'd', 'abcsum09', 3 from dual union all 
     select 'd', null  , null from dual 
    ) 
-- end of test data (not part of the SQL query); query begins BELOW THIS LINE 
select group_id, file_date, flag, 
     case when count(*) over (partition by group_id) = 2 
       and 
       count(distinct file_date) over (partition by group_id) = 1 then 0 
      when to_number(substr(file_date, -2)) = 16      then 1 
      when to_number(substr(file_date, -2)) between 10 and 15   then 2 
      else                 3 end 
       as date_flag 
from test_data 
where file_date is not null and flag is not null 
; 

GROUP_ID FILE_DATE FLAG DATE_FLAG 
-------- --------- ---- ---------- 
a  abcsum16  3   1 
b  abcsum15  4   2 
c  abcwin16  7   0 
c  abcwin16  7   0 
d  abcsum09  3   3 

5 rows selected. 
関連する問題