2

工場のリストを含むテーブルがあります(工場IDと工場名)

Factory ID    Factory Name
1001          Factory1
1002          Factory2
1003          Factory3

ユーザーは、毎月、各工場の履歴テーブルにいくつかのデータをアップロードします。また、同じ月の既存の工場データも別のユーザーによって上書きされます。したがって、履歴テーブルは次のようになります。

Factory ID   Month UploadedValue UploadedBy UploadedOn
1001         01    250           User1      29.11.2016 07:28 PM
1002         01    102.12        User1      29.11.2016 07:28 PM
1001         01    400           User2      30.11.2016 12.00 PM

ここで、各工場と毎月のレポートを生成する必要があります。これは最新のアップロード (誰がいつアップロードしたか) であり、アップロードがない場合は「アップロードなし」と表示されます。これは以下のようになります。

   Factory ID    Factory Name   Month   Last Upload by   Last Upload on
    1001          Factory1       01      User2            30.11.2016 12.00 PM
    1002          Factory2       01      User1            29.11.2016 07:28 PM
    1003          Factory3       01      Not Uploaded     Not Uploaded

これを手に入れるのを手伝ってください。解析機能をつけてみました。しかし運がない。

4

2 に答える 2

2

機能を使用できますRANK()。テーブルがFACとであると仮定するとFAC_HIST、コードは次のようになります

SELECT fid, fname, month, last_uploaded_by, last_uploaded_on
  FROM ( select fh.fid fid
              , fh.fname fname
              , COALESCE(fd.month, 1) month
              , COALESCE(RANK() FIRST OVER (PARTITION BY fd.fid, fd.month 
                                                ORDER BY fd.last_uploaded_on DESC)
                         , -1) rnk
              , COALESCE(fd.uploaded_by, 'not uploaded') last_uploaded_by
              , COALESCE(fd.last_uploaded_on, 'not uploaded') last_uploaded_on
           FROM fac fh
           LEFT OUTER JOIN fac_hist fd
             ON fh.fid = fd.fid
                )
 WHERE rnk <= 1;
于 2016-11-29T14:19:48.490 に答える
0

毎月の各工場の最新の更新のみを取得するにはgroup by factory_idmonth「更新」テーブルで と を選択しますmax(updatedon)。他の列については、 を使用できますkeep (dense_rank last...)。これらはすべて (分析ではなく) 集計関数であり、必要以上の作業は必要ありません。

クエリのもう 1 つの部分は、データの高密度化です。Oracle の最近のバージョンでは、これは「パーティションの外部結合」で実行できます (このトピックの詳細については Google を参照)。概念を完全に説明するために、入力データに 2 番目の「月」を追加しました (出力も参照してください)。'Not Uploaded'注-代わりに気にしませんでしたnull-本当に必要な場合は、すべての値をラップしてそのテキストcoalesce()に置き換えるnullことができますが、それが追加するものはわかりません。nullまったく同じ情報を伝えます。

with
     factories ( factory_id, factory_name ) as (
       select 1001, 'Factory1' from dual union all
       select 1002, 'Factory2' from dual union all
       select 1003, 'Factory3' from dual
     ),
     updates ( factory_id, month, uploadedvalue, uploadedby, uploadedon ) as (
       select 1001, '01', 250   , 'User1', to_date('29.11.2016 07:28 PM', 'dd.mm.yyyy hh:mi AM') from dual union all
       select 1002, '01', 102.12, 'User1', to_date('29.11.2016 07:28 PM', 'dd.mm.yyyy hh:mi AM') from dual union all
       select 1001, '01', 400   , 'User2', to_date('30.11.2016 12.00 PM', 'dd.mm.yyyy hh:mi AM') from dual
     ),
     months ( month ) as (
       select '01' from dual union all
       select '02' from dual
     )
select fm.factory_id, fm.factory_name, fm.month, s.uploadedvalue, s.uploadedby, 
       s.uploadedon
from   (
select factory_id, month, 
       min(uploadedvalue) keep (dense_rank last order by uploadedon) as uploadedvalue,
       min(uploadedby)    keep (dense_rank last order by uploadedon) as uploadedby,
       max(uploadedon) as uploadedon
from   updates
group by factory_id, month
) s
partition by (month)
right outer join (select * from factories cross join months) fm  
         on fm.factory_id = s.factory_id
        and fm.month      = s.month
order by month, factory_id
;

出力:

FACTORY_ID  FACTORY_NAME  MONTH  UPLOADEDVALUE  UPLOADEDBY  UPLOADEDON
----------  ------------  -----  -------------  ----------  -------------------
1001        Factory1      01               400  User2       30.11.2016 12.00 PM
1002        Factory2      01            102.12  User1       29.11.2016 07:28 PM
1003        Factory3      01            
1001        Factory1      02            
1002        Factory2      02            
1003        Factory3      02            
于 2016-11-29T16:55:12.930 に答える