在PostgreSQL中查找给定月份的最后一个工作日
用法:如果月末是星期六或星期日,则返回上一个星期五,否则使用月末
示例:
如何在PostgreSQL SQL中编写它?
到目前为止我所拥有的是(仅返回月末,但月末或星期日不存在月末):
SELECT as_of_dt, sum(bank_shr_bal) as bank_shr_bal
FROM hm_101.vw_gl_bal
WHERE as_of_dt = (date_trunc('MONTH', as_of_dt) + INTERVAL '1 MONTH - 1 day')::date
GROUP BY 1
由于
答案 0 :(得分:1)
with s as (
select *, (date_trunc('MONTH', as_of_dt) + INTERVAL '1 MONTH - 1 day')::date last_day
from
hm_101.vw_gl_bal
)
SELECT
as_of_dt,
gl_acct_nbr,
cc_nbr,
sum(bank_shr_bal) as bank_shr_bal
FROM s
WHERE as_of_dt = (
last_day
-
(extract(dow from last_day) = 5)::int
-
2 * (extract(dow from last_day) = 6)::int
)
GROUP BY 1,2,3
答案 1 :(得分:1)
A calendar table确实简化了这些查询的SQL。 (表“工作日”实际上是一个基于日历表的视图。它的结构应该是显而易见的。)
select max(cal_date)
from weekdays
where cal_date < '2013-05-01'
或
select max(cal_date)
from weekdays
where cal_date between '2013-04-01' and '2013-04-30'
答案 2 :(得分:0)
一种解决方案是使用CTE,在数据中找到每月的最后一天和每个月的实际最后一天
WITH s1
as
(
SELECT
date_part('YEAR', as_of_dt) AOD_Year
,date_part('MONTH', as_of_dt) AOD_Month
,(date_trunc('MONTH', as_of_dt) + INTERVAL '1 MONTH - 1 day')::date AOD_MonthEnd
,max(as_of_dt) AOD_LastFound
FROM hm_101.vw_gl_bal
where (date_trunc('MONTH', as_of_dt) + INTERVAL '1 MONTH - 1 day')::date = '2013-03-31'
group by 1, 2, 3
)
SELECT
s1.AOD_MonthEnd
,s1.AOD_LastFound
,sum(v.bank_shr_bal) as bank_shr_bal
FROM hm_101.vw_gl_bal v
INNER JOIN s1
on v.as_of_dt = s1.AOD_LastFound
WHERE v.as_of_dt = '2013-03-29'
GROUP BY 1, 2
答案 3 :(得分:0)
你想要做的是从月的最后一天(你有)之后的0到2天之间删除。
通过提取星期几(DOW)并检查它是0(星期日)还是6(星期六),我们知道要删除多少天。
你可以这样做:
... - INTERVAL '1 day' * CASE date_part('DOW', last_day_of_month)
WHEN 0 THEN 2 -- Sunday, remove 2 days.
WHEN 6 THEN 1 -- Saturday, remove 1 day.
ELSE 0 -- Don't remove any days.
END
为了便于阅读,我没有在那里包含完整的last_day_of_month计算。
答案 4 :(得分:0)
实际上,您可以在没有CTE或存储过程的情况下执行此操作。
select
case
when extract(dow from last_day_of_month) = 0
then last_day_of_month - 2
when extract(dow from last_day_of_month) = 6
then last_day_of_month - 1
else
last_day_of_month
end as last_weekday_of_month
from(
SELECT (date_trunc('MONTH', as_of_dt)
+ INTERVAL '1 MONTH - 1 day')::date as last_day_of_month
from hm_101.vw_gl_bal
)subquery;
答案 5 :(得分:0)
select
case
when extract(dow from first_day_of_month) = 0 then first_day_of_month
when extract(dow from first_day_of_month) = 1 then first_day_of_month - 1
when extract(dow from first_day_of_month) = 2 then first_day_of_month - 2
when extract(dow from first_day_of_month) = 3 then first_day_of_month - 3
when extract(dow from first_day_of_month) = 4 then first_day_of_month - 4
when extract(dow from first_day_of_month) = 5 then first_day_of_month - 5
when extract(dow from first_day_of_month) = 6 then first_day_of_month - 6
end as first_weekday_of_month,
case
when extract(dow from last_day_of_month) = 6 then last_day_of_month
when extract(dow from last_day_of_month) = 5 then last_day_of_month - 6
when extract(dow from last_day_of_month) = 4 then last_day_of_month - 5
when extract(dow from last_day_of_month) = 3 then last_day_of_month - 4
when extract(dow from last_day_of_month) = 2 then last_day_of_month - 3
when extract(dow from last_day_of_month) = 1 then last_day_of_month - 2
when extract(dow from last_day_of_month) = 0 then last_day_of_month - 1
end as last_weekday_of_month
from(
SELECT
(date_trunc('month', current_date) -'7day'::interval)::date first_day_of_month,
(date_trunc('month', current_date) -'1day'::interval)::date as last_day_of_month
)subquery;