sql >> Database >  >> RDS >> PostgreSQL

Genereer een reeks weekintervallen voor een bepaalde maand

SELECT generate_series(date_trunc('week', date '2013-02-01' + interval '6 days')
                     , date_trunc('week', date '2013-02-01' + interval '1 month - 1 day')
                     , interval '1 week')::date AS day
UNION  SELECT date '2013-02-01'
ORDER  BY 1;

Deze variant heeft geen subselectie nodig, GREATEST of GROUP BY en genereert alleen de vereiste rijen. Eenvoudiger, sneller. Het is goedkoper om UNION één rij.

  • Voeg 6 dagen toe aan de eerste dag van de maand voor date_trunc('week', ...) om de eerste maandag van de maand . te berekenen .

  • Voeg 1 maand toe en trek 1 dag af voor date_trunc('week', ...) om de laatste maandag van de maand . te krijgen .
    Dit kan gemakkelijk in een enkel interval worden gestopt uitdrukking:'1 month - 1 day'

  • UNION (niet UNION ALL ) de eerste dag van de maand om het toe te voegen, tenzij het al als maandag is opgenomen.

  • Merk op dat date + interval resulteert in timestamp , wat hier het optimum is. Gedetailleerde uitleg:

Automatisering

U kunt het begin van de datumreeks in een CTE opgeven:

WITH t(d) AS (SELECT date '2013-02-01')  -- enter 1st of month once
SELECT generate_series(date_trunc('week', d + interval '6 days')
                     , date_trunc('week', d + interval '1 month - 1 day')
                     , interval '1 week')::date AS day
FROM   t
UNION  SELECT d FROM t
ORDER  BY 1;

Of wikkel het voor het gemak in een eenvoudige SQL-functie met herhaalde oproepen:

CREATE OR REPLACE FUNCTION f_week_starts_this_month(date)
  RETURNS SETOF date AS
$func$
SELECT generate_series(date_trunc('week', $1 + interval '6 days')
                     , date_trunc('week', $1 + interval '1 month - 1 day')
                     , interval '1 week')::date AS day
UNION
SELECT $1
ORDER  BY 1
$func$  LANGUAGE sql IMMUTABLE;

Bel:

SELECT * FROM f_week_starts_this_month('2013-02-01');

Je zou de datum doorgeven voor de eerste dag van de maand, maar het werkt voor elke datum. Jij de eerste dag en alle maandagen voor de volgende maand.



  1. Recordvelden afdrukken in PL/SQL

  2. Oracle Pl/SQL:Loop door XMLTYPE-knooppunten

  3. Haal het laatste record van elke maand in MySQL....?

  4. H2 postgresql-modus lijkt niet te werken voor mij