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
的四分之一,那么已经有很多例子了,比如:
如何计算任意日期的四分之一
一些测试日期:
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日期获取上个季度的第一天和上个季度的最后一天