我需要根据订单的请求交货日期在postgres查询中安排一些项目。例如,订单在星期一(例如20120319)有要求的交货,订单需要在前一个工作日(20120316)准备。
关于最直接方法的想法?我愿意添加日期表。我认为必须有一个比一长串案例陈述更好的方法,使用: SELECT EXTRACT(来自TIMESTAMP'DowstAMP'2001-02-16 20:38:40'的DOW);
答案 0 :(得分:7)
要上一个工作日:
select max(s.a) as work_day
from (
select s.a::date
from generate_series('2012-01-02'::date, '2050-12-31', '1 day') s(a)
where extract(dow from s.a) between 1 and 5
except
select holiday_date
from holiday_table
) s
where s.a < '2012-03-19'
;
如果您想要下一个工作日,只需反转查询。
答案 1 :(得分:7)
这可以让你上一个工作日。
SELECT
CASE (EXTRACT(ISODOW FROM current_date)::integer) % 7
WHEN 1 THEN current_date-3
WHEN 0 THEN current_date-2
ELSE current_date-1
END AS previous_business_day
答案 2 :(得分:4)
SELECT y.d AS prep_day
FROM (
SELECT generate_series(dday - 8, dday - 1, interval '1d')::date AS d
FROM (SELECT '2012-03-19'::date AS dday) x
) y
LEFT JOIN holiday h USING (d)
WHERE h.d IS NULL
AND extract(isodow from y.d) < 6
ORDER BY y.d DESC
LIMIT 1;
应该更快才能根据需要生成多天。我在交货前一周生成。这应该涵盖所有可能性。
isodow
as extract parameter比dow
更方便地测试工作日。
min()
/ max()
,ORDER BY / LIMIT 1
,这与我查询中的几行有关。
要按降序排列几个候选天数,而不仅仅是首选,请更改LIMIT 1
。
我将dday
(投放日)放在子查询中,因此您只需输入一次。您可以输入任意date
或timestamp
字面值。无论哪种方式,都会转换为date
。
答案 3 :(得分:0)
CREATE TABLE Holidays (Holiday, PrecedingBusinessDay) AS VALUES
('2012-12-25'::DATE, '2012-12-24'::DATE),
('2012-12-26'::DATE, '2012-12-24'::DATE);
SELECT Day, COALESCE(PrecedingBusinessDay, PrecedingMondayToFriday)
FROM
(SELECT Day, Day - CASE DATE_PART('DOW', Day)
WHEN 0 THEN 2
WHEN 1 THEN 3
ELSE 1
END AS PrecedingMondayToFriday
FROM TestDays) AS PrecedingMondaysToFridays
LEFT JOIN Holidays ON PrecedingMondayToFriday = Holiday;
您可能想要重命名一些标识符: - )。