PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

SQL -- изчисляване на крайни дати от дадена начална дата с произволни прекъсвания

Вместо просто да разглеждате продължителността на семестрите или празнините между тях, можете да генерирате списък на всички дати, които са в рамките на един семестър, като използвате generate_series() , като това:

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

(Демо на SQLFiddle )

Това присвоява на всеки ден, който е през семестъра, произволен, но последователен „номер на деня“, пропускайки всички празнини между семестрите.

След това можете да използвате това като подзаявка/CTE JOIN ed във вашата таблица с ученици:първо намерете „номера на деня“ на началната им дата, след това добавете 7 * n_weeks за да намерите „номера на деня“ на тяхната крайна дата и накрая да се присъедините, за да намерите действителната дата за този „номер на деня“.

Това предполага, че не е необходима специална обработка за частични седмици - т.е. ако n_weeks е 4, студентът трябва да бъде записан за 28 дни, които са в рамките на продължителността на семестъра. Подходът може да се адаптира за измерване на седмици (преминете 1 week като последен аргумент на generate_series() ), с допълнителната стъпка за намиране коя седмица е start_date на ученика попада в.

Ето пълна заявка (демонстрация на 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. Как заобикаляте ограничението на размера на Docker.qcow2 в Docker за Mac?

  2. Sqlalchemy дублира клаузата WHERE на FROM

  3. Ще даде ли UUID като първичен ключ в PostgreSQL лоша производителност на индекса?

  4. Естествен сорт, поддържащ големи числа

  5. ON DELETE SET NULL в postgres