use*_*026 6 sql oracle oracle11g oracle-analytics
我需要帮助写一篇关于oracle的老化报告.报告应该像:
aging file to submit total 17
aging file to submit 0-2 days 3
aging file to submit 2-4 days 4
aging file to submit 4-6 days 4
aging file to submit 6-8 days 2
aging file to submit 8-10 days 4
Run Code Online (Sandbox Code Playgroud)
我可以为每个部分创建一个查询,然后将所有结果联合起来,如:
select 'aging file to submit total ' || count(*) from FILES_TO_SUBMIT where trunc(DUE_DATE) > trunc(sysdate) -10
union all
select 'aging file to submit 0-2 days ' || count(*) from FILES_TO_SUBMIT where trunc(DUE_DATE) <= trunc(sysdate) and trunc(DUE_DATE) >= trunc(sysdate-2)
union all
select 'aging file to submit 2-4 days ' || count(*) from FILES_TO_SUBMIT where trunc(DUE_DATE) <= trunc(sysdate-2) and trunc(DUE_DATE) >= trunc(sysdate-4) ;
Run Code Online (Sandbox Code Playgroud)
我想知道是否有更好的方法使用oracle分析函数或任何其他可以获得更好性能的查询?
样本数据:
CREATE TABLE files_to_submit(file_id int, file_name varchar(255),due_date date);
INSERT INTO FILES_TO_SUBMIT(FILE_ID,FILE_NAME,DUE_DATE) VALUES ( 1, 'file_' || 1, sysdate);
INSERT INTO FILES_TO_SUBMIT(FILE_ID,FILE_NAME,DUE_DATE) VALUES ( 2, 'file_' || 2, sysdate -5);
INSERT INTO FILES_TO_SUBMIT(FILE_ID,FILE_NAME,DUE_DATE) VALUES ( 3, 'file_' || 3, sysdate -4);
INSERT INTO FILES_TO_SUBMIT(FILE_ID,FILE_NAME,DUE_DATE) VALUES ( 4, 'file_' || 4, sysdate);
INSERT INTO FILES_TO_SUBMIT(FILE_ID,FILE_NAME,DUE_DATE) VALUES ( 5, 'file_' || 5, sysdate-3);
INSERT INTO FILES_TO_SUBMIT(FILE_ID,FILE_NAME,DUE_DATE) VALUES ( 6, 'file_' || 6, sysdate-7);
INSERT INTO FILES_TO_SUBMIT(FILE_ID,FILE_NAME,DUE_DATE) VALUES ( 7, 'file_' || 7, sysdate-10);
INSERT INTO FILES_TO_SUBMIT(FILE_ID,FILE_NAME,DUE_DATE) VALUES ( 8, 'file_' || 8, sysdate-12);
INSERT INTO FILES_TO_SUBMIT(FILE_ID,FILE_NAME,DUE_DATE) VALUES ( 9, 'file_' || 9, sysdate-3);
INSERT INTO FILES_TO_SUBMIT(FILE_ID,FILE_NAME,DUE_DATE) VALUES ( 10, 'file_' || 10, sysdate-5);
INSERT INTO FILES_TO_SUBMIT(FILE_ID,FILE_NAME,DUE_DATE) VALUES ( 11, 'file_' || 11, sysdate-6);
INSERT INTO FILES_TO_SUBMIT(FILE_ID,FILE_NAME,DUE_DATE) VALUES ( 12, 'file_' || 12, sysdate-7);
INSERT INTO FILES_TO_SUBMIT(FILE_ID,FILE_NAME,DUE_DATE) VALUES ( 13, 'file_' || 13, sysdate-5);
INSERT INTO FILES_TO_SUBMIT(FILE_ID,FILE_NAME,DUE_DATE) VALUES ( 14, 'file_' || 14, sysdate-4);
INSERT INTO FILES_TO_SUBMIT(FILE_ID,FILE_NAME,DUE_DATE) VALUES ( 15, 'file_' || 15, sysdate-2);
INSERT INTO FILES_TO_SUBMIT(FILE_ID,FILE_NAME,DUE_DATE) VALUES ( 16, 'file_' || 16, sysdate-6);
INSERT INTO FILES_TO_SUBMIT(FILE_ID,FILE_NAME,DUE_DATE) VALUES ( 17, 'file_' || 17, sysdate-6);
INSERT INTO FILES_TO_SUBMIT(FILE_ID,FILE_NAME,DUE_DATE) VALUES ( 18, 'file_' || 18, sysdate-5);
INSERT INTO FILES_TO_SUBMIT(FILE_ID,FILE_NAME,DUE_DATE) VALUES ( 19, 'file_' || 19, sysdate-10);
INSERT INTO FILES_TO_SUBMIT(FILE_ID,FILE_NAME,DUE_DATE) VALUES ( 20, 'file_' || 20, sysdate-9);
DROP TABLE files_to_submit;
Run Code Online (Sandbox Code Playgroud)
您可以使用这种简单的方法获取所有日期的报告(不含总数):
select
'aging file to submit '|| trunc(dist/2)*2 ||'-'|| (trunc(dist/2)*2+2) || ' days: ' || count(*)
from (
select trunc(sysdate) - trunc(DUE_DATE) as dist
from FILES_TO_SUBMIT
--where trunc(DUE_DATE) > trunc(sysdate) -10
)
group by trunc(dist/2)
order by trunc(dist/2);
Run Code Online (Sandbox Code Playgroud)
唯一重要的是天数(dist(ance)字段).
如果您想在同一扫描中同时拥有总计:
select
'aging file to submit '||
case
when trunc(dist/2) is null
then 'Total '
else trunc(dist/2)*2 ||'-'|| (trunc(dist/2)*2+2) || ' days: '
end ||
count(*)
from (
select trunc(sysdate) - trunc(DUE_DATE) as dist
from FILES_TO_SUBMIT
where trunc(DUE_DATE) > trunc(sysdate) -10
)
group by rollup(trunc(dist/2))
order by trunc(dist/2)
nulls first;
Run Code Online (Sandbox Code Playgroud)
提示:如果您有数百天的历史记录,那么索引将非常有用.(注意:如果你的表很大,> 100Milion,索引的创建需要一些时间)
create index index_name on files_to_submit(due_date);
Run Code Online (Sandbox Code Playgroud)
然后将条件更改为:
where DUE_DATE > trunc(sysdate) - 10
Run Code Online (Sandbox Code Playgroud)
这会加快你的速度
请允许我建议WIDTH_BUCKET。这会将日期范围划分为相等大小。由于您希望将 10 天的范围分成 2 天的组,因此存储桶大小将为 10 / 2 = 5。
询问:
SELECT
CASE GROUPING(bucket)
WHEN 1
THEN 'aging file to submit Total'
ELSE 'aging file to submit ' || (bucket-1)*2 || '-' || (bucket)*2 || ' days'
END AS bucket_number,
COUNT(1) AS files
FROM (
SELECT
WIDTH_BUCKET(due_date, sysdate, sysdate-10, 5) bucket
FROM
files_to_submit
WHERE
due_date >= sysdate-10
)
GROUP BY
ROLLUP(bucket)
ORDER BY
bucket NULLS FIRST;
Run Code Online (Sandbox Code Playgroud)
结果:
BUCKET_NUMBER FILES
------------------------------------ ----------
aging file to submit Total 17
aging file to submit 0-2 days 2
aging file to submit 2-4 days 3
aging file to submit 4-6 days 6
aging file to submit 6-8 days 5
aging file to submit 8-10 days 1
Run Code Online (Sandbox Code Playgroud)