提问人:Dawid_K 提问时间:10/31/2023 最后编辑:Dawid_K 更新时间:11/2/2023 访问量:55
如何跳过一天而不是闰年
How to skip one day for not leap years
问:
我生成了一个表格,其中包含从 2000-01-01 到 2039-12-31(ISO 格式)的日期。日历包含闰年。现在,基于此,我想创建另一个具有一些转换的表。我有两列问题。
Fiscal_year_day_nr
和。Fiscal_quarter_daynr
每年有 366 天,但不是闰年,则跳过 2 月 29 日。所以 2 月 28 日是 59 天,3 月 1 日是 61 天。对于闰年,2月29日有一个60号的一天。Fiscal_year_day_nr
我怎样才能在不闰年跳过那一天?假设该表包含一列,该列以所有日期命名,并基于此表创建新表,并使用 和 。calendar
date
date
Fiscal_year_day_nr
Fiscal_quarter_daynr
我正在使用 Redshift SQL (RSQL)。
答:
create table calendar as with recursive g("date") as
(select '2000-01-01'::date union all select "date"+1 from g
where "date" <= '2039-12-31'::date)
select "date" from g;
为了保持连续编号,您可以使用 extract(
) 和 row_number()
窗口函数,窗口定义基于 date_trunc():
演示
create table new_table as
select "date",
extract(yearday from "date") as "Fiscal_year_day_nr",
row_number()over(partition by date_trunc('year',"date"),
date_trunc('quarter',"date")
order by "date")
as "Fiscal_quarter_daynr"
from calendar
order by "date";
日期 | Fiscal_year_day_nr | Fiscal_quarter_daynr |
---|---|---|
2023-12-31 | (非闰年缩短) 365 | 92 |
2024-01-01 | 1 | 1 |
2024-02-28 | 59 | 59 |
2024-02-29 | (闰年) 60 | 60 |
2024-03-01 | 61 | 61 |
2024-03-31 | 91 | 91 |
2024-04-01 | 92 | 1 |
2025-02-28 | 59 | 59 |
2025-03-01 | (无间隙) 60 | 60 |
2025-03-31 | 90 | 90 |
2025-04-01 | 91 | 1 |
如果您确实希望看到非闰年的编号差距,则可以在适当的时候有条件地添加日期。转换条件以简化:boolean
int
create table calendar_skipping_feb29 as
select "date",
extract(yearday from "date")
+(extract(month from date_trunc('year',"date")::date+59) = 3
and 60<=extract(yearday from "date"))::int
AS "Fiscal_year_day_nr",
row_number()over(partition by date_trunc('year',"date"),
date_trunc('quarter',"date")
order by "date")
+(extract(month from date_trunc('year',"date")::date+59) = 3
and 60<=extract(yearday from "date")
and 1 =extract(quarter from "date"))::int
AS "Fiscal_quarter_daynr"
from calendar;
如果一年中的第 60 天(1 月 1 日)在 3 月(月),则它是非闰年,因此从第 60 天开始,您将添加 to ( cast to is )。 做同样的事情,但仅限于第一季度。+59
3
1
"Fiscal_year_day_nr"
true
int
1
"Fiscal_quarter_daynr"
日期 | Fiscal_year_day_nr | Fiscal_quarter_daynr |
---|---|---|
2023-12-31 | (间隙增加的非闰年) 366 | 92 |
2024-01-01 | 1 | 1 |
2024-02-28 | 59 | 59 |
2024-02-29 | (闰年不受影响) 60 | 60 |
2024-03-01 | 61 | 61 |
2024-03-31 | 91 | 91 |
2024-04-01 | 92 | 1 |
2025-02-28 | 59 | 59 |
2025-03-01 | (间隙加) 61 | 61 |
2025-03-31 | 91 | 91 |
2025-04-01 | 92 | 1 |
优雅是美好的,但永远不要低估蛮力的力量。您只需使用标准 Postgres 提供的日期函数即可实现您正在寻找的日期函数,即使是版本 8(Redshift 的基础)和一些辅助函数。(见演示)
create or replace function is_leap_year(year_in integer)
returns boolean
language plpgsql
immutable
as $$
declare
lvar date;
begin
lvar = make_date(year_in,02,29);
return true;
exception
when others then
return false;
end;
$$;
with std_calendar(gregorian_dt) as
( select generate_series('2000-01-01'::date
,'2004-03-01'::date
,interval '1 day'
)::date
) --select * from std_calendar
insert into fy_table(gre_date
,fiscal_year_day_nr
,fiscal_quarter
,fiscal_quarter_daynr
)
select gregorian_dt::date
, extract(doy from gregorian_dt)
+ case when not is_leap_year(extract(year from gregorian_dt)::integer)
and extract(month from gregorian_dt) > 2
then 1
else 0
end fydn
, extract(quarter from gregorian_dt) fg
, extract( days from (gregorian_dt - date_trunc('quarter', gregorian_dt))) + 1
+ case when not is_leap_year(extract(year from gregorian_dt)::integer)
and extract(month from gregorian_dt) > 2
then 1
else 0
end fqdnr
from std_calendar;
您没有定义您的会计年度,因此演示假设它与日历年相对应,并且您希望使用相同的跳过日功能。
评论
to_char()
to_timestamp()
datediff()