Daripada hanya melihat panjang semester atau jarak antar semester, Anda dapat membuat daftar semua tanggal dalam satu semester menggunakan generate_series()
, seperti ini:
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
Ini menetapkan setiap hari selama satu semester sebuah "nomor hari" yang sewenang-wenang tetapi berurutan, melewatkan semua jarak antar semester.
Anda kemudian dapat menggunakan ini sebagai sub-kueri/CTE JOIN
ed ke tabel siswa Anda:pertama-tama temukan "nomor hari" dari tanggal mulai mereka, lalu tambahkan 7 * n_weeks
untuk menemukan "nomor hari" dari tanggal akhir mereka, dan akhirnya bergabung kembali untuk menemukan tanggal sebenarnya untuk "nomor hari" tersebut.
Ini mengasumsikan bahwa tidak ada penanganan khusus yang diperlukan untuk sebagian minggu - yaitu jika n_weeks
adalah 4, mahasiswa harus terdaftar selama 28 hari yang dalam jangka waktu satu semester. Pendekatan ini dapat disesuaikan untuk mengukur minggu (lulus 1 week
sebagai argumen terakhir untuk generate_series()
), dengan langkah tambahan untuk menemukan start_date
minggu mana siswa jatuh ke dalam.
Berikut kueri lengkapnya (demo SQLFiddle di sini ):
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