计算Postgres最近的工作日

时间:2012-03-16 20:04:50

标签: sql postgresql date

我需要根据订单的请求交货日期在postgres查询中安排一些项目。例如,订单在星期一(例如20120319)有要求的交货,订单需要在前一个工作日(20120316)准备。

关于最直接方法的想法?我愿意添加日期表。我认为必须有一个比一长串案例陈述更好的方法,使用:     SELECT EXTRACT(来自TIMESTAMP'DowstAMP'2001-02-16 20:38:40'的DOW);

4 个答案:

答案 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 parameterdow更方便地测试工作日。

  • min() / max()ORDER BY / LIMIT 1,这与我查询中的几行有关。

  • 要按降序排列几个候选天数,而不仅仅是首选,请更改LIMIT 1

  • 我将dday(投放日)放在子查询中,因此您只需输入一次。您可以输入任意datetimestamp字面值。无论哪种方式,都会转换为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;

您可能想要重命名一些标识符: - )。