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
生徒のテーブルに編集:最初に開始日の「日番号」を見つけてから、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