Postgresql 如何在Postgress中获得给定月份的周范围
这是我当前的实施方案Postgresql 如何在Postgress中获得给定月份的周范围,postgresql,date,Postgresql,Date,这是我当前的实施方案 SELECT date_trunc('month', do_date::date)::date as starting_of_the_month, (date_trunc('month', do_date::date) + interval '1 month' - interval '1 day')::date as ending_of_the_month, case when 1 + FLOOR((EXTRACT(DAY FROM do_da
SELECT
date_trunc('month', do_date::date)::date as starting_of_the_month,
(date_trunc('month', do_date::date) + interval '1 month' - interval '1 day')::date as ending_of_the_month,
case when 1 + FLOOR((EXTRACT(DAY FROM do_date) - 1) / 7) = 1
THEN date_trunc('week', do_date)::date || ' - ' ||
(date_trunc('week', do_date) + '6 days') ::date end as week1,
case when 1 + FLOOR((EXTRACT(DAY FROM do_date) - 1) / 7) = 2
THEN date_trunc('week', do_date)::date || ' - ' ||
(date_trunc('week', do_date) + '6 days') ::date end as week2,
case when 1 + FLOOR((EXTRACT(DAY FROM do_date) - 1) / 7) = 3
THEN date_trunc('week', do_date)::date || ' - ' ||
(date_trunc('week', do_date) + '6 days') ::date end as week3,
case when 1 + FLOOR((EXTRACT(DAY FROM do_date) - 1) / 7) = 4
THEN date_trunc('week', do_date)::date || ' - ' ||
(date_trunc('week', do_date) + '6 days') ::date end as week4,
case when 1 + FLOOR((EXTRACT(DAY FROM do_date) - 1) / 7) = 5
THEN date_trunc('week', do_date)::date || ' - ' ||
(date_trunc('week', do_date) + '6 days') ::date end as week5
FROM sales_dos
WHERE date_trunc('month', do_date::date)::date >= '2021-02-01' AND date_trunc('month', do_date::date)::date < '2021-02-28'
选择
日期(“月”,执行日期::日期)::作为该月开始日期的日期,
(日期(“月”,日期::日期)+间隔“1个月”-间隔“1天”)::日期为该月的结束日期,
1+楼层((提取(从开工日期算起的日期)-1)/7)=1时的情况
然后date|trunc('week',do|date)::date | |'-'||
(日期(“周”,完成日期)+“6天”):日期结束为第1周,
1+楼层((摘录(从开工日期算起的日期)-1)/7)=2时的情况
然后date|trunc('week',do|date)::date | |'-'||
(日期(“周”,完成日期)+“6天”):日期结束为第2周,
1+楼层时的情况(摘录(从开工日期算起的日期)-1)/7)=3
然后date|trunc('week',do|date)::date | |'-'||
(日期(“周”,完成日期)+“6天”):日期结束为第3周,
1+楼层时的情况((摘录(从开工日期算起的日期)-1)/7)=4
然后date|trunc('week',do|date)::date | |'-'||
(日期(“周”,完成日期)+“6天”):日期结束为第4周,
1+楼层时的情况(摘录(从开工日期算起的日期)-1)/7)=5
然后date|trunc('week',do|date)::date | |'-'||
(日期(“周”,完成日期)+“6天”):日期结束为第5周
来自销售部
其中日期(“月”,执行日期::日期)::日期>='2021-02-01'和日期(“月”,执行日期::日期)::日期<'2021-02-28'
这是我目前的输出:
我希望输出显示如下:
第一周:2021-02-01-2021-02-07
第2周:2021-02-08-2021-02-14
第3周:2021-02-15-2021-02-21
第4周:2021-02-22-2021-02-28
第5周:-我首先要简化为:
extract(day from do_date)::int / 7 + 1 as week_in_month
然后,使用该方法进行重点分析。我将首先简化为:
extract(day from do_date)::int / 7 + 1 as week_in_month
然后使用。将重点放在使用标准日历的混合ISO上。您正在使用ISO周的开始和结束时间,但不是所有周都是7天,而是可能会截断第一周和/或最后一周
这方面的需求变化实际上并不广泛。对于初始查询,返回ISO周的开始日期,而不是当月的第一天。然后,主查询检查第1周,如果是,则生成该月的第1周。唯一的问题是确定ISO周开始日期。为此,我刚刚加入了一个函数,我已经为此专门使用了一段时间。对week_days函数的更改被标记为--,因此您需要的是一个带有标准日历的混合ISO。您正在使用ISO周的开始和结束时间,但不是所有周都是7天,而是可能会截断第一周和/或最后一周
这方面的需求变化实际上并不广泛。对于初始查询,返回ISO周的开始日期,而不是当月的第一天。然后,主查询检查第1周,如果是,则生成该月的第1周。唯一的问题是确定ISO周开始日期。为此,我刚刚加入了一个函数,我已经为此专门使用了一段时间。对week_days函数的更改被标记--这里是另一种方法(例如2021年1月)
与
t as(选择日期(“月”,“2021-03-11”::日期)为今天),即2021年1月的任何日期
s作为
(
选择d::date,d::date+6 ed,从d中提取('isodow')wd
从t开始,生成_序列(每天,每天+间隔“1个月-1天”,间隔“1天”)d
)
选择格式('Week%s',extract(从d开始的日期)::integer/7+1)作为weekname、d、ed
从s
其中wd=1;
这里是另一种方法(例如2021年1月)
与
t as(选择日期(“月”,“2021-03-11”::日期)为今天),即2021年1月的任何日期
s作为
(
选择d::date,d::date+6 ed,从d中提取('isodow')wd
从t开始,生成_序列(每天,每天+间隔“1个月-1天”,间隔“1天”)d
)
选择格式('Week%s',extract(从d开始的日期)::integer/7+1)作为weekname、d、ed
从s
其中wd=1;
请参见@Bohemian修改答案和/或答案。在2021年4月测试时,此查询输出的周范围不正确,例如:('2021-04-23')。您需要指定预期结果,并正确定义周的含义。从您的样本数据推断,本月的第1周从本月的第1天开始,为期7天,除最后一周在本月的最后一天结束外,每周都是如此。这正是查询为2021年4月生成的结果。很抱歉没有详细说明问题,是的,实际上我需要一个月的周初从该月的开始日期开始,到周日结束。与2021年4月一样,第1周应为(01-04-2021至04-04-2021)、第2周(05-04-2021至11-04-2021)和第5周(26-04-2021至30-04-2021),请参见修订答案。请参见@Bohemian修改答案和/或答案。在2021年4月测试时,此查询输出的周范围不正确,例如:('2021-04-23')。您需要指定预期结果,也要正确定义你所说的周。从您的样本数据推断,本月的第1周从本月的第1天开始,为期7天,除最后一周在本月的最后一天结束外,每周都是如此。这正是查询为2021年4月生成的结果。很抱歉没有详细说明问题,是的,实际上我需要一个月的周初从该月的开始日期开始,到周日结束。与2021年4月一样,第1周应为(01-04-2021至04-04-2021)、第2周(05-04-2021至11-04-2021)和第5周(26-04-2021至30-04-2021),请参见修订后的答案。在2019年3月进行尝试时,此查询给出的周数不正确。第1周的预期输出应为2019年3月1日至2019年3月3日,但此查询给出的第1周结果为2019年3月4日至2019年3月10日。此查询在重试时给出的周数不正确
create or replace
function week_dates( do_date_in date)
returns table (ween_num integer, first_date date, last_date date)
language sql
immutable strict
as $$
with recursive date_list(week_num,first_date,terminate_date) as
( select 1
, date_trunc('month', do_date_in)::timestamp
, (date_trunc('month', do_date_in) + interval '1 month' - interval '1 day')::timestamp
union all
select week_num+1, (first_date+interval '7 day'), terminate_date
from date_list
where first_date+interval '6 day' < terminate_date::timestamp
)
select week_num
, first_date::date
, case when (first_date+interval '6 day')::date > terminate_date
then terminate_date::date
else (first_date+interval '6 day')::date
end last_date
from date_list;
$$;
select week1s
, case when week5e is null
then week4e
else week5e
end "end of month"
, week1s || ' - ' || week1e
, week2s || ' - ' || week2e
, week3s || ' - ' || week3e
, week4s || ' - ' || week4e
, week5s || ' - ' || week5e
from ( select max(case when (week_num=1) then first_date else NULL end) as week1s
, max(case when (week_num=1) then last_date else NULL end) as week1e
, max(case when (week_num=2) then first_date else NULL end) as week2s
, max(case when (week_num=2) then last_date else NULL end) as week2e
, max(case when (week_num=3) then first_date else NULL end) as week3s
, max(case when (week_num=3) then last_date else NULL end) as week3e
, max(case when (week_num=4) then first_date else NULL end) as week4s
, max(case when (week_num=4) then last_date else NULL end) as week4e
, max(case when (week_num=5) then first_date else NULL end) as week5s
, max(case when (week_num=5) then last_date else NULL end) as week5e
from week_dates(current_date)
) w ;