PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Generuj serie interwałów tygodniowych dla danego miesiąca

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;

Ten wariant nie wymaga podselekcji, GREATEST lub GROUP BY i generuje tylko wymagane wiersze. Prościej, szybciej. Taniej jest UNION jeden rząd.

  • Dodaj 6 dni do pierwszego dnia miesiąca przed date_trunc('week', ...) aby obliczyć pierwszy poniedziałek miesiąca .

  • Dodaj 1 miesiąc i odejmij 1 dzień przed date_trunc('week', ...) aby uzyskać ostatni poniedziałek miesiąca .
    Można to wygodnie umieścić w jednym interval wyrażenie:'1 month - 1 day'

  • UNION (nie UNION ALL ) pierwszego dnia miesiąca, aby go dodać, chyba że jest już uwzględniony jako poniedziałek.

  • Zwróć uwagę, że date + interval wyniki w timestamp , który jest tutaj optymalny. Szczegółowe wyjaśnienie:

Automatyzacja

Możesz podać początek serii dat w 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;

Lub zapakuj go w prostą funkcję SQL dla wygody z powtarzającymi się wywołaniami:

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;

Zadzwoń:

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

Datę można przekazać na pierwszy dzień miesiąca, ale działa to w przypadku każdego data. Ty pierwszy dzień i wszystkie poniedziałki w następnym miesiącu.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Hibernacja:Utwórz indeks

  2. Dział ( / ) nie daje mojej odpowiedzi w postgresql

  3. ScalikeJDBC:Pula połączeń nie została jeszcze zainicjowana.(name:'default)

  4. Aby zignorować zduplikowane klucze podczas „kopiowania z” w postgresql

  5. Jak zapisać dane z przecinkiem zmieniającym się, które przechodzi przez wyzwalacz?