毎月の各工場の最新の更新のみを取得するにはgroup by factory_id
、month
「更新」テーブルで と を選択します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