简体   繁体   English

Oracle - 如何重复每年/每月/每周的查询

[英]Oracle - How to repeat query for every year/month/week

I've made a query to get the rows from my chosen columns where the date is 2018 December: 我已经进行了一个查询,以获取我所选列的日期为2018年12月的行:

SELECT myColumn1, myColumn2 
FROM MyTable
WHERE to_char(myColumn_DATE, 'YYYY/MM') = '2018/12'

This is quite simple and I can now use these rows to create some further logic. 这很简单,我现在可以使用这些行来创建一些进一步的逻辑。 However what if I need to repeat this for every month in a given year, or even every week? 但是,如果我需要在给定的一年,甚至每个星期每个月重复一次呢?

I'm exporting the query results into separate excel tables, so I guess I would have to manually check the correct date intervals every time and can't aggregate the data for a whole year/month/etc. 我将查询结果导出到单独的excel表中,所以我想我必须每次都手动检查正确的日期间隔,并且不能聚合整年/月/等的数据。 Isn't there some PL/SQL approach to avoid this tedious repetition? 是不是有一些PL / SQL方法来避免这种繁琐的重复?

Assume you're on a day from December 2018, and your aim is to populate the table MyTable2 through the data from the table MyTable . 假设你是从2018十二月一日,你的目的是为了填充表MyTable2通过从表中的数据MyTable

Firstly, let's create MyTable2 without data : 首先,让我们创建没有数据的MyTable2

create table MyTable2 as
select myColumn1, myColumn2 
  from MyTable
 where 1 = 9;

and then create a procedure by which populate MyTable2 on the last day of every month 然后创建一个过程,在每个月的最后一天填充MyTable2

create or replace procedure pr_populate_Mytable2 is
begin
   insert into MyTable2
   select myColumn1, myColumn2 
     from MyTable
    where to_char(myColumn_DATE, 'YYYY/MM') = to_char(sysdate,'YYYY/MM');
 commit;
end;

by calling the procedure from a dbms_scheduler as 通过从dbms_scheduler调用该过程作为

declare
    v_job_name varchar2(32) := 'jb_populate_Mytable2';
begin  
    dbms_scheduler.create_job(
        job_name => v_job_name,
        job_type => 'STORED_PROCEDURE',
        job_action => 'pr_populate_Mytable2', 
        start_date => to_date('31-12-2018 20:00:00', 'dd-mm-yyyy hh24:mi:ss'),
        repeat_interval => 'FREQ=MONTHLY; BYMONTHDAY=-1; BYHOUR=21;',
        auto_drop => false,
        comments => 'Populates our table on the last day of every month at 21 o''clock ');

    dbms_scheduler.enable(v_job_name);    
end;

starts at 8pm on the last day of december, and repeats on every upcoming last days of the months at 9pm in the future. 从12月的最后一天晚上8点开始,并在将来的每个月的最后几天重复播放。

You can use the CONNECT BY LEVEL <= trick to generate rows, and then use a combination of date functions to generate the relevant dates. 您可以使用CONNECT BY LEVEL <=技巧生成行,然后使用日期函数的组合生成相关日期。

--Months for the current year.
select add_months(trunc(sysdate, 'year'), level-1) the_month
from dual
connect by level <= 12;

THE_MONTH
---------
2019-01-01
2019-02-01
2019-03-01
2019-04-01
2019-05-01
2019-06-01
2019-07-01
2019-08-01
2019-09-01
2019-10-01
2019-11-01
2019-12-01

Then create an inline view with that query, and join it to the main table: 然后使用该查询创建内联视图,并将其连接到主表:

select *
from
(
    --Months for the current year.
    select add_months(trunc(sysdate, 'year'), level-1) the_month
    from dual
    connect by level <= 12
) months
left join mytable
    on months.the_month = trunc(mycolumn_date, 'month');

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM