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

SQL -- obliczanie dat zakończenia od podanej daty rozpoczęcia z arbitralnymi przerwami

Zamiast patrzeć tylko na długości semestrów lub przerwy między nimi, możesz wygenerować listę wszystkich dat, które mieszczą się w semestrze, używając generate_series() , tak:

SELECT
  row_number() OVER () as day_number,
  day
FROM
(
  SELECT
    generate_series(start_date, end_date, '1 day') as day
  FROM
    semesters
) as day_series
ORDER BY 
  day

(demonstracja SQLFiddle )

To przypisuje każdemu dniu, który jest w trakcie semestru, arbitralny, ale sekwencyjny „numer dnia”, pomijając wszystkie przerwy między semestrami.

Następnie możesz użyć tego jako podzapytania/CTE JOIN ed do tabeli uczniów:najpierw znajdź „numer dnia” ich daty rozpoczęcia, a następnie dodaj 7 * n_weeks aby znaleźć „numer dnia” ich daty końcowej, a na koniec dołączyć z powrotem, aby znaleźć rzeczywistą datę dla tego „numeru dnia”.

Zakłada się, że nie jest wymagana żadna specjalna obsługa przez częściowe tygodnie - np. jeśli n_weeks 4 lata, student musi być przyjęty na 28 dni, które mieszczą się w czasie trwania semestru. Podejście można dostosować do mierzenia tygodni (zalicz 1 week jako ostatni argument generate_series() ), z dodatkowym krokiem znajdowania start_date tygodnia ucznia wpada.

Oto pełne zapytanie (demo SQLFiddle ):

WITH semester_days AS
(
  SELECT
    semester_id,
    row_number() OVER () as day_number,
    day_date::date
  FROM
  (
    SELECT
      id as semester_id,
      generate_series(start_date, end_date, '1 day') as day_date
    FROM
      semesters
  ) as day_series
  ORDER BY 
    day_date
)
SELECT
  S.id as student_id,
  S.start_date,
  SD_start.semester_id as start_semester_id,
  S.n_weeks,
  SD_end.day_date as end_date,
  SD_end.semester_id as end_semester_id
FROM
  students as S
JOIN
  semester_days as SD_start
  On SD_start.day_date = S.start_date
JOIN
  semester_days as SD_end
  On SD_end.day_number = SD_start.day_number + (7 * S.n_weeks)
ORDER BY
  S.start_date



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak zwrócić wartość z procedury składowanej (nie funkcji)?

  2. Wyodrębnij miesiąc od pola daty

  3. Łączenie tablic w klauzuli group by

  4. Migracje Django :relacja już istnieje

  5. PostgreSQL, niestandardowe agregaty