sql >> Database teknologi >  >> RDS >> PostgreSQL

Generer serier af ugeintervaller for en given måned

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;

Denne variant behøver ikke et undervalg, GREATEST eller GROUP BY og genererer kun de nødvendige rækker. Enklere, hurtigere. Det er billigere at UNION en række.

  • Tilføj 6 dage til den første dag i måneden før date_trunc('week', ...) for at beregne den første mandag i måneden .

  • Tilføj 1 måned og træk 1 dag før date_trunc('week', ...) for at få den sidste mandag i måneden .
    Dette kan bekvemt fyldes i et enkelt interval udtryk:'1 month - 1 day'

  • UNION (ikke UNION ALL ) den første dag i måneden for at tilføje den, medmindre den allerede er inkluderet som mandag.

  • Bemærk at date + interval resulterer i timestamp , hvilket er det optimale her. Detaljeret forklaring:

Automatisering

Du kan angive starten på datoserien i en CTE:

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;

Eller pak den ind i en simpel SQL-funktion for nemheds skyld med gentagne opkald:

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;

Ring til:

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

Du ville passere datoen for den første dag i måneden, men den virker for alle dato. Du den første dag og alle mandage i den følgende måned.



  1. Øg værdien i MySQL-opdateringsforespørgsel

  2. SQL OPDATERING

  3. PHP MySQL vælg tilfældige rækker

  4. Hvordan kan jeg matche en kommasepareret liste med en værdi?