Frage Wie erhalte ich die Anzahl der aktuellen Sonntage in psql?


So erhalten Sie die Gesamtzahl der Sonntage für ein bestimmtes Datum in postgresql


5
2018-02-17 14:56


Ursprung


Antworten:


Die Gesamtzahl der Sonntage für ein bestimmtes Datum kann nur 0 oder 1 sein.

Wenn Sie jedoch die Anzahl der Sonntage innerhalb eines bestimmten Datumsbereichs festlegen möchten, ist Ihre Kalendertabelle am besten geeignet. Um herauszufinden, wie viele Sonntage im Februar dieses Jahres sind, würde ich einfach

select count(*) 
from calendar
where cal_date between '2011-02-01' and '2011-02-28' and
      day_of_week = 'Sun';

oder

select count(*)
from calendar
where year_of_date = 2011 and
      month_of_year = 2 and 
      day_of_week = 'Sun';

Hier ist eine grundlegende Kalendertabelle, mit der Sie beginnen können. Ich habe auch eine PostgreSQL-Funktion zum Auffüllen der Kalendertabelle hinzugefügt. Ich habe das nicht in 8.3 getestet, aber ich bin mir ziemlich sicher, dass ich keine Funktionen verwende, die 8.3 nicht unterstützt.

Beachten Sie, dass die "Dow" -Teile davon ausgehen, dass Ihre Tage in Englisch sind. Sie können diese Teile jedoch leicht bearbeiten, um sie an jede Sprache anzupassen. (Ich denke. Aber ich könnte mich "leicht" irren.)

-- Table: calendar

-- DROP TABLE calendar;

CREATE TABLE calendar
(
  cal_date date NOT NULL,
  year_of_date integer NOT NULL,
  month_of_year integer NOT NULL,
  day_of_month integer NOT NULL,
  day_of_week character(3) NOT NULL,
  CONSTRAINT calendar_pkey PRIMARY KEY (cal_date),
  CONSTRAINT calendar_check CHECK (year_of_date::double precision = date_part('year'::text, cal_date)),
  CONSTRAINT calendar_check1 CHECK (month_of_year::double precision = date_part('month'::text, cal_date)),
  CONSTRAINT calendar_check2 CHECK (day_of_month::double precision = date_part('day'::text, cal_date)),
  CONSTRAINT calendar_check3 CHECK (day_of_week::text = 
CASE
    WHEN date_part('dow'::text, cal_date) = 0::double precision THEN 'Sun'::text
    WHEN date_part('dow'::text, cal_date) = 1::double precision THEN 'Mon'::text
    WHEN date_part('dow'::text, cal_date) = 2::double precision THEN 'Tue'::text
    WHEN date_part('dow'::text, cal_date) = 3::double precision THEN 'Wed'::text
    WHEN date_part('dow'::text, cal_date) = 4::double precision THEN 'Thu'::text
    WHEN date_part('dow'::text, cal_date) = 5::double precision THEN 'Fri'::text
    WHEN date_part('dow'::text, cal_date) = 6::double precision THEN 'Sat'::text
    ELSE NULL::text
END)
)
WITH (
  OIDS=FALSE
);
ALTER TABLE calendar OWNER TO postgres;

-- Index: calendar_day_of_month

-- DROP INDEX calendar_day_of_month;

CREATE INDEX calendar_day_of_month
  ON calendar
  USING btree
  (day_of_month);

-- Index: calendar_day_of_week

-- DROP INDEX calendar_day_of_week;

CREATE INDEX calendar_day_of_week
  ON calendar
  USING btree
  (day_of_week);

-- Index: calendar_month_of_year

-- DROP INDEX calendar_month_of_year;

CREATE INDEX calendar_month_of_year
  ON calendar
  USING btree
  (month_of_year);

-- Index: calendar_year_of_date

-- DROP INDEX calendar_year_of_date;

CREATE INDEX calendar_year_of_date
  ON calendar
  USING btree
  (year_of_date);

Und eine rudimentäre Funktion, um den Tisch zu füllen. Ich habe das auch nicht in 8.3 getestet.

-- Function: insert_range_into_calendar(date, date)

-- DROP FUNCTION insert_range_into_calendar(date, date);

CREATE OR REPLACE FUNCTION insert_range_into_calendar(from_date date, to_date date)
  RETURNS void AS
$BODY$

DECLARE
    this_date date := from_date;
BEGIN

    while (this_date <= to_date) LOOP
        INSERT INTO calendar (cal_date, year_of_date, month_of_year, day_of_month, day_of_week)
        VALUES (this_date, extract(year from this_date), extract(month from this_date), extract(day from this_date),
        case when extract(dow from this_date) = 0 then 'Sun'
             when extract(dow from this_date) = 1 then 'Mon'
             when extract(dow from this_date) = 2 then 'Tue'
             when extract(dow from this_date) = 3 then 'Wed'
             when extract(dow from this_date) = 4 then 'Thu'
             when extract(dow from this_date) = 5 then 'Fri'
             when extract(dow from this_date) = 6 then 'Sat'
        end);
        this_date = this_date + interval '1 day';
    end loop;       

END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;

4
2018-02-17 15:07



Sie brauchen EXTRAKT:

SELECT 
    EXTRACT(DOW FROM DATE '2011-02-16') = 0; -- 0 is Sunday

Dies kann zu wahr oder falsch führen, es ist ein Sonntag oder ist es nicht. Ich habe keine Ahnung, was du mit "total number" meinst, denn das wird immer 0 sein (das Datum ist kein Sonntag) oder 1 (die angegebenen Daten sind ein Sonntag).

Edit: So ähnlich?

SELECT 
    COUNT(*)
FROM
    generate_series(timestamp '2011-01-01', '2011-03-01', '1 day') AS g(mydate)
WHERE
    EXTRACT(DOW FROM mydate) = 0;

8
2018-02-17 15:03