计算两个日期之间的工作日数

Ech*_*yak 0 postgresql time-series plpgsql

我正在尝试获取 plpgsql 中两个日期之间的工作日数。以下是我的代码:

CREATE FUNCTION weekdays(DATE, DATE) RETURNS INTEGER AS
$$
DECLARE
    d date := $1;
    weekdays integer := 0
BEGIN

LOOP
    IF select extract(dow from date d) != 6 or select extract(dow from date d) != 0
      weekdays := weekdays +1
    END IF
    d := d + 1;
    EXIT WHEN d > $2;
END LOOP;
RETURN weekdays;
END;
$$
LANGUAGE 'plpgsql' IMMUTABLE;
Run Code Online (Sandbox Code Playgroud)

但是,我不断收到以下错误:

Unterminated dollar quote started at position 56 in SQL
CREATE FUNCTION weekdays(DATE, DATE) RETURNS INTEGER AS $$ DECLARE d date := $1.
Expected terminating $$
Run Code Online (Sandbox Code Playgroud)

Erw*_*ter 5

该错误是由于缺少;weekdays integer := 0;。加上更多此类错误。这会起作用

CREATE  OR REPLACE FUNCTION weekdays(date, date)
  RETURNS integer AS
$func$
DECLARE
   d        date := $1;
   weekdays int  := 0;
BEGIN
   LOOP
      IF extract(isodow from d) < 6 THEN  -- simpler
         weekdays := weekdays + 1;
      END IF;
      d := d + 1;
      EXIT WHEN d > $2;
   END LOOP;
   RETURN weekdays;
END
$func$  LANGUAGE plpgsql IMMUTABLE;
Run Code Online (Sandbox Code Playgroud)

但我建议改用这个更简单、更快的 SQL 函数

CREATE OR REPLACE FUNCTION weekdays_sql(date, date)
  RETURNS integer AS
$func$
SELECT count(*)::int
FROM   generate_series($1, $2, interval '1d') d
WHERE  extract(isodow FROM d) < 6;
$func$  LANGUAGE sql IMMUTABLE;
Run Code Online (Sandbox Code Playgroud)

大范围的进一步性能改进成为可能。有关的: