我有一张表,上面有付款期的开始和结束日期。
我需要分配给定日历年的支付期号。规则是1月1日为期间1,即使其开始日期为上一年的12月。例如,1/31 / 2000-1 / 13/2001应该是2001年的期间1。如果在支付期间中包含明年的1月1日,则明年的期间1开始(12/30 / 2001-1 / 12/2002是2002年的支付期1)。
我需要为PostgreSQL或PostgreSQL函数创建一个查询。我想将期间1分配给目标年份中的最小日期,并递增支付期间编号,直到支付期间达到28或日历年结束(在下一年的1/1之前)。我不确定自己的逻辑以及SELECT语句中使用表中不存在的calendar_pp的部分。
开始结束
1/14/2001 1/27/2001<br/>
1/28/2001 2/10/2001<br/>
2/11/2001 2/24/2001<br/>
2/25/2001 3/10/2001<br/>
3/11/2001 3/24/2001<br/>
3/25/2001 4/7/2001<br/>
4/8/2001 4/21/2001<br/>
4/22/2001 5/5/2001<br/>
5/6/2001 5/19/2001<br/>
5/20/2001 6/2/2001<br/>
6/3/2001 6/16/2001<br/>
6/17/2001 6/30/2001<br/>
7/1/2001 7/14/2001<br/>
7/15/2001 7/28/2001<br/>
7/29/2001 8/11/2001<br/>
8/12/2001 8/25/2001<br/>
8/26/2001 9/8/2001<br/>
9/9/2001 9/22/2001<br/>
9/23/2001 9/30/2001<br/>
10/1/2001 10/6/2001<br/>
10/7/2001 10/20/2001<br/>
10/21/2001 11/3/2001<br/>
11/4/2001 11/17/2001<br/>
11/18/2001 12/1/2001<br/>
12/2/2001 12/15/2001<br/>
12/16/2001 12/29/2001<br/>
12/30/2001 1/12/2002<br/>
CREATE OR REPLACE FUNCTION calendar_pp(end_date DATE)
RETURNS TABLE (
start_date_col DATE,
end_date_col DATE,
calendar_pp INTEGER)
AS $$
DECLARE
calendar_pp INTEGER ;
counter INTEGER := 0 ;
start_date DATE := TO_CHAR(TO_DATE(begin_payperiod_date,'MM/DD/YY'),'MM/DD') ;
end_date_year INTEGER := CAST((TO_CHAR(TO_DATE(min(end_payperiod_date),'MM/DD/YY'),'YYYY')) AS INTEGER) ;
target_year INTEGER := 2001 ; --1st pay period = 12/31/2000-1/13/2001
BEGIN
WHILE counter <= 28 LOOP --max pay period = 28
counter := counter + 1 ;
calendar_pp := calendar_pp + 1 ;
end_date_year := end_date_year + 1 ;
target_year := target_year + 1 ;
--assign pay period starting with 1 till end_date becomes next year
RETURN QUERY
SELECT TO_DATE(begin_payperiod_date,'MM/DD/YY'), TO_DATE(end_payperiod_date,'MM/DD/YY'), calendar_pp
FROM actacc.payperiod_conversion_all_years
WHERE end_date_year = target_year AND calendar_pp is null
order by TO_DATE(begin_payperiod_date,'MM/DD/YY')
END LOOP;
END; $$
LANGUAGE 'plpgsql' ;
这是预期的结果。
开始结束付款期
1/14/2001 1/27/2001 2<br/>
1/28/2001 2/10/2001 3<br/>
2/11/2001 2/24/2001 4<br/>
2/25/2001 3/10/2001 5<br/>
3/11/2001 3/24/2001 6<br/>
3/25/2001 4/7/2001 7<br/>
4/8/2001 4/21/2001 8<br/>
4/22/2001 5/5/2001 9<br/>
5/6/2001 5/19/2001 10<br/>
5/20/2001 6/2/2001 11<br/>
6/3/2001 6/16/2001 12<br/>
6/17/2001 6/30/2001 13<br/>
7/1/2001 7/14/2001 14<br/>
7/15/2001 7/28/2001 15<br/>
7/29/2001 8/11/2001 16<br/>
8/12/2001 8/25/2001 17<br/>
8/26/2001 9/8/2001 18<br/>
9/9/2001 9/22/2001 19<br/>
9/23/2001 9/30/2001 20<br/>
10/1/2001 10/6/2001 21<br/>
10/7/2001 10/20/2001 22<br/>
10/21/2001 11/3/2001 23<br/>
11/4/2001 11/17/2001 24<br/>
11/18/2001 12/1/2001 25<br/>
12/2/2001 12/15/2001 26<br/>
12/16/2001 12/29/2001 27<br/>
12/30/2001 1/12/2002 1<br/>
答案 0 :(得分:0)
我不确定这28个要求。您是说即使我们不在1月1日附近,工资期也应该重新设置?假设这是不正确的,我认为这应该可行:
with dates as (SELECT start_date, end_date
FROM (VALUES
('12/31/2000'::date,'1/13/2001'::date),
('1/14/2001','1/27/2001'),
('1/28/2001','2/10/2001'),
('2/11/2001','2/24/2001'),
('2/25/2001','3/10/2001'),
('3/11/2001','3/24/2001'),
('3/25/2001','4/7/2001'),
('4/8/2001','4/21/2001'),
('4/22/2001','5/5/2001'),
('5/6/2001','5/19/2001'),
('5/20/2001','6/2/2001'),
('6/3/2001','6/16/2001'),
('6/17/2001','6/30/2001'),
('7/1/2001','7/14/2001'),
('7/15/2001','7/28/2001'),
('7/29/2001','8/11/2001'),
('8/12/2001','8/25/2001'),
('8/26/2001','9/8/2001'),
('9/9/2001','9/22/2001'),
('9/23/2001','9/30/2001'),
('10/1/2001','10/6/2001'),
('10/7/2001','10/20/2001'),
('10/21/2001','11/3/2001'),
('11/4/2001','11/17/2001'),
('11/18/2001','12/1/2001'),
('12/2/2001','12/15/2001'),
('12/16/2001','12/29/2001'),
('12/30/2001','1/12/2002')
) v (start_date, end_date)
)
select start_date, end_date, rank() OVER (partition by date_trunc('year', end_date) ORDER BY end_date) FROM dates;
start_date | end_date | rank
------------+------------+------
2000-12-31 | 2001-01-13 | 1
2001-01-14 | 2001-01-27 | 2
2001-01-28 | 2001-02-10 | 3
2001-02-11 | 2001-02-24 | 4
2001-02-25 | 2001-03-10 | 5
2001-03-11 | 2001-03-24 | 6
2001-03-25 | 2001-04-07 | 7
2001-04-08 | 2001-04-21 | 8
2001-04-22 | 2001-05-05 | 9
2001-05-06 | 2001-05-19 | 10
2001-05-20 | 2001-06-02 | 11
2001-06-03 | 2001-06-16 | 12
2001-06-17 | 2001-06-30 | 13
2001-07-01 | 2001-07-14 | 14
2001-07-15 | 2001-07-28 | 15
2001-07-29 | 2001-08-11 | 16
2001-08-12 | 2001-08-25 | 17
2001-08-26 | 2001-09-08 | 18
2001-09-09 | 2001-09-22 | 19
2001-09-23 | 2001-09-30 | 20
2001-10-01 | 2001-10-06 | 21
2001-10-07 | 2001-10-20 | 22
2001-10-21 | 2001-11-03 | 23
2001-11-04 | 2001-11-17 | 24
2001-11-18 | 2001-12-01 | 25
2001-12-02 | 2001-12-15 | 26
2001-12-16 | 2001-12-29 | 27
2001-12-30 | 2002-01-12 | 1
(28 rows)