我有一个表包含工厂列表(工厂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
请帮忙解决这个问题。我尝试过分析功能。但没有运气。
答案 0 :(得分: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;
答案 1 :(得分:0)
要仅获取每个月每个工厂的最新更新,您可以在“更新”表格中month
和max(updatedon)
,然后选择keep (dense_rank last...)
。对于其他列,您可以使用'Not Uploaded'
。所有这些都是聚合函数(而不是分析函数) - 并且您不需要做更多的工作。
查询的另一部分是数据密集化。在更新版本的Oracle中,可以使用“分区外连接”(Google阅读有关此主题的更多信息)来完成此操作。我在输入数据中添加了第二个“月”以充分说明概念(请参阅输出)。注意 - 我没有使用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
<强>输出强>:
=IIF(SUM(Fields!VT.Value)=0,"0:00",
IIF(SUM(Fields!VT.Value)< 0,"-"&Format(DateAdd("s",ABS(SUM(Fields!VT.Value)), "00:00"), "HH:mm"),
Format(DateAdd("s",ABS(SUM(Fields!VT.Value)), "00:00"), "HH:mm")))