【问题标题】:Oracle - How to repeat query for every year/month/weekOracle - 如何每年/每月/每周重复查询
【发布时间】:2019-04-02 20:03:53
【问题描述】:

我已进行查询以从我选择的列中获取日期为 2018 年 12 月的行:

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

这很简单,我现在可以使用这些行来创建一些进一步的逻辑。但是,如果我需要在给定年份的每个月甚至每周重复一次呢?

我将查询结果导出到单独的 Excel 表中,所以我想我每次都必须手动检查正确的日期间隔,并且无法汇总整年/月/等的数据。难道没有一些 PL/SQL 方法可以避免这种乏味的重复吗?

【问题讨论】:

  • 感谢 MattSom。您是否正在寻找一个包含全年数据但按周划分结果的查询——例如包括一年中的一周字段?或者您是否只想迭代地重复不同周的查询?
  • 我将继续重复查询,因为我将在结果行上使用大量聚合函数来获取该时间段的一些测量值。当然,如果划分全年是一种更简单的方法,我也非常愿意接受这样的建议!
  • 如何导出数据?到目前为止,您只是显示给定范围内的所有行。您可以将其重写为WHERE myColumn_DATE >= DATE '2018-12-01' AND myColumn_DATE < DATE '2019-01-01' 或更通用的绑定变量到WHERE myColumn_DATE >= :date_start AND myColumn_DATE < :date_after。当然,您可以使用某种编程语言在循环中运行此查询,例如VBA。
  • @ThorstenKettner 说起来很尴尬,但目前我正在通过 SQL Developer 手动导出它。我仍在尝试找出我的 sqlplus cli。

标签: oracle date plsql


【解决方案1】:

假设您在 2018 年 12 月的某一天,您的目标是通过表 MyTable 中的数据填充表 MyTable2。

首先,让我们创建没有数据的MyTable2:

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

然后创建一个在每个月的最后一天填充 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;

通过从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;

从 12 月最后一天晚上 8 点开始,并在未来每个月的最后几天晚上 9 点重复。

【讨论】:

  • 哇,有趣的方法!但是,现在我需要获取过去时间段的所有信息,以进行更复杂的数据分析。这个选项仍然让我很感兴趣!所以你是说,用这个所谓的dbms_scheduler 调用一个过程会在给定时间运行我的脚本吗?如果我的服务器意外关闭,它会永远错过实际的查询吗?
  • 谢谢。是的,即使在数据库实例复活后也会在给定时间运行。如果您的数据库版本是11gR2 +,您可以通过将job_queue_processes 值设置为零来阻止它们在重新启动后运行。顺便说一句,我去年夏天去过的布达佩斯是一个令人钦佩的城市:)希望你在那里过得很好。
  • 感谢您的信息!也谢谢你的美言,现在天气暖和了,这座城市肯定很可爱! :))
【解决方案2】:

您可以使用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

然后使用该查询创建一个内联视图,并将其连接到主表:

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');

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多