PL/SQL(如何计算任何一年任何季度的第一天和最后一天)

Posted

技术标签:

【中文标题】PL/SQL(如何计算任何一年任何季度的第一天和最后一天)【英文标题】:PL/SQL (How to calculate the first and last day of any quarter of any year) 【发布时间】:2013-08-31 14:51:46 【问题描述】:

我有一张桌子,per_all_peopl_f,有以下列:

name  person_id  emp_flag  effective_start_date   effective_end_date   DOJ
    --------------------------------------------------------------------------------    
    ABC   123          Y       30-MAR-2011              30-MAR-2013       10-FEB-2011
    ABC   123          Y       24-FEB-2011              27-FEB-2011       10-FEB-2011
    DEF   345          N       10-APR-2012              30-DEC-4712       15-SEP-2011

有许多条目 (1000+) 具有重复的数据和不同的生效开始日期。

我必须计算员工人数。即每季度退出公司的员工人数。

必须提取以下列:

2012 年员工人数(第一季度) 2013 年员工人数(第一季度) 两个员工人数的差异 % 差异

这必须每季度进行一次。也就是说,无论我通过哪个季度,劳动力人数都应该按照这个计算。

我写的查询是

CREATE OR REPLACE FUNCTION function_name
  (l_end_date ,l_start_date  ) 
  RETURN number;
  IS 
    l_emp

  BEGIN
    select count(distinct papf.person_id)
      into l_emp
      from per_all_people_f papf
     where papf.emp_flag ='Y'
       and effective_start_date >=l_end_date
       and effective_end_date <=l_start_date ;

    return l_emp; 
END function_name;


create xx_pack_name  body
is 
crate or replace procedure proc_name( l_quarter number,
                      p_person_id number,
                      l_year number )
    cursor cur_var
    is 
       select function_name(l_start_date ,l_end_date ) EMP_2012,
              function_name(l_start_date1,l_end_date1 ) EMP_2013,
              function_name(l_start_date ,l_end_date )-function_name(l_start_date1,l_end_date1 ) Diff
         from dual;


Begin
if(l_year=2012)

if l_quarter =1
then
l_start_date :='01-Jan-2013';
l_end_date :='31-APR-2013';

elsif l_quarter =2
then
l_start_date :='01-May-2013';
l_end_date :='31-Aug-2013';

else
l_start_date :='01-Sep-2013';
l_end_date :='31-Dec-2013';

end if;
end if;
if(l_year=2013)

then 

if l_quarter =1
then
l_start_date :='01-Jan-2013';
l_end_date :='31-APR-2013';

elsif l_quarter =2
then
l_start_date :='01-May-2013';
l_end_date :='31-Aug-2013';

else
l_start_date :='01-Sep-2013';
l_end_date :='31-Dec-2013';

end if;
end if;

for cur_val in cur_var 
loop
dbms_output.put_line(cur_var.emp_2012 || cur_var.emp_2013 ||cur_var.diff )

end loop



end xx_pack_name  ;

这个包太长了。

有没有其他方法可以计算任何一年季度的最后一天和第一天????

当我计算时

百分比函数名(l_start_date ,l_end_date )-function_name(l_start_date1,l_end_date1) /100

选择语句中没有输出

【问题讨论】:

上一季度的人数与下一季度的人数之差与离开的人数不一样。 是的...这就是为什么必须计算差异 您似乎将季度员工人数定义为“在本季度任何时候受雇的唯一人员总数”。或者其他的东西。您的代码“effective_start_date >=l_end_date 和 effective_end_date 查看有效日期是对特定员工在表中进行任何更改的日期。我通过函数得到结果。有没有更好的方法来计算任何季度的最后一天和第一天 【参考方案1】:

我觉得这个问题非常令人困惑。如果真正的问题是如何计算任意DATE 的四分之一,那么已经有很多例子了,比如:

Oracle - break dates into quarters Find First and Last Day of the last Quarter in ORACLE

如何计算任意日期的四分之一

一些测试日期:

create table lots_of_dates as
select trunc(sysdate - level * 7) as d
from dual
connect by level <= 52;

找到宿舍:

select d,
       to_char(d, 'YYYY-Q') as QUARTER,
       trunc(d, 'Q') as Q_FIRST_DAY,
       add_months(trunc(d, 'Q'), 3) - 1 as Q_LAST_DAY
from lots_of_dates
order by 1;

结果:

D                  QUARTE Q_FIRST_DAY        Q_LAST_DAY
------------------ ------ ------------------ ------------------
02-SEP-12          2012-3 01-JUL-12          30-SEP-12
09-SEP-12          2012-3 01-JUL-12          30-SEP-12
16-SEP-12          2012-3 01-JUL-12          30-SEP-12
23-SEP-12          2012-3 01-JUL-12          30-SEP-12
30-SEP-12          2012-3 01-JUL-12          30-SEP-12
07-OCT-12          2012-4 01-OCT-12          31-DEC-12
14-OCT-12          2012-4 01-OCT-12          31-DEC-12
21-OCT-12          2012-4 01-OCT-12          31-DEC-12
28-OCT-12          2012-4 01-OCT-12          31-DEC-12
04-NOV-12          2012-4 01-OCT-12          31-DEC-12
11-NOV-12          2012-4 01-OCT-12          31-DEC-12
...

返回一个季度的第一天和最后一天的 PL/SQL 过程

季度的开始日期和结束日期对于除年份部分之外的所有年份都是不变的。 IE。第二季度总是从每年的 4 月 1 日开始,到 6 月 30 日结束。因此可以固定日期和月份,只需要调整年份部分。

一个函数只能返回一个值,因此子例程被实现为过程。我还为该过程提供了一个函数包装器:

-- raises CASE_NOT_FOUND for non-existing quarters
create or replace procedure get_quarter_days(
  p_year in number,
  p_quarter in number,
  p_first_day out date,
  p_last_day out date
) deterministic as
begin
  case p_quarter
    when 1 then
      p_first_day := to_date(p_year || '-01-01', 'YYYY-MM-DD');
      p_last_day  := to_date(p_year || '-03-31', 'YYYY-MM-DD');
    when 2 then
      p_first_day := to_date(p_year || '-04-01', 'YYYY-MM-DD');
      p_last_day  := to_date(p_year || '-06-30', 'YYYY-MM-DD');
    when 3 then
      p_first_day := to_date(p_year || '-07-01', 'YYYY-MM-DD');
      p_last_day  := to_date(p_year || '-09-30', 'YYYY-MM-DD');
    when 4 then
      p_first_day := to_date(p_year || '-10-01', 'YYYY-MM-DD');
      p_last_day  := to_date(p_year || '-12-31', 'YYYY-MM-DD');
  end case;
end;
/
show errors

create or replace function get_quarter_first_day(
  p_year in number,
  p_quarter in number
) return date deterministic as
  v_first_day date;
  v_last_day date;
begin
  get_quarter_days(p_year, p_quarter, v_first_day, v_last_day);
  return v_first_day;
end;
/
show errors

create or replace function get_quarter_last_day(
  p_year in number,
  p_quarter in number
) return date deterministic as
  v_first_day date;
  v_last_day date;
begin
  get_quarter_days(p_year, p_quarter, v_first_day, v_last_day);
  return v_last_day;
end;
/
show errors

如何使用上述子程序:

declare
  v_first_day date;
  v_last_day date;
begin
  get_quarter_days(2011, 1, v_first_day, v_last_day);
  dbms_output.put_line(v_first_day || ' - ' || v_last_day);
  get_quarter_days(2012, 2, v_first_day, v_last_day);
  dbms_output.put_line(v_first_day || ' - ' || v_last_day);
  get_quarter_days(2013, 3, v_first_day, v_last_day);
  dbms_output.put_line(v_first_day || ' - ' || v_last_day);
  get_quarter_days(2014, 4, v_first_day, v_last_day);
  dbms_output.put_line(v_first_day || ' - ' || v_last_day);

  dbms_output.put_line(get_quarter_first_day(2015, 1) || ' - ' ||
                       get_quarter_last_day(2015, 1));
end;
/

【讨论】:

您好,我想创建一个函数,在该函数中我将传递年份和季度作为参数,并且该季度的第一天和最后一天应该到来。

以上是关于PL/SQL(如何计算任何一年任何季度的第一天和最后一天)的主要内容,如果未能解决你的问题,请参考以下文章

Oracle SQL日期获取上个季度的第一天和上个季度的最后一天

php求当前季度的第一天和最后一天

SQL Server学习记录之获取每月每季度每年第一天和最后一天

甲骨文下个季度的第一天

获取一年的第一天和最后一天

从 PL/SQL 游标中获取所有结果的任何简单方法?