我有以下架构:
计划表示重复活动的时间表。
# Table name: schedules
#
# id :integer not null, primary key
# start_date :date
# end_date :date
天数表示活动发生的时间表的WEEKday。
# Table name: days
#
# id :integer not null, primary key
# schedule_id :integer
# wday :integer
TimeSlots表示活动可能发生的小时数(可能每天很多)。
# Table name: time_slots
#
# id :integer not null, primary key
# day_id :integer
# start_time :time not null
# end_time :time not null
示例数据集可以是:
鉴于上面的例子(在下面的SQL中表示),我想在六月份的每个星期一返回一条记录,包括它们的日历日期。
2017年6月有4个星期一,所以上面的例子看起来像:
id | wday | calendar_date |
----+------+---------------+
1 | 2 | 2017-06-05 |
1 | 2 | 2017-06-12 |
1 | 2 | 2017-06-19 |
1 | 2 | 2017-06-26 |
有人能引导我朝着正确的方向前进吗?
在下面设置PSQL:
CREATE TABLE schedules (
id integer NOT NULL,
start_date date,
end_date date);
CREATE TABLE days (
id integer NOT NULL,
schedule_id integer,
wday integer);
CREATE TABLE time_slots (
id integer NOT NULL,
start_time time,
end_time time,
day_id integer);
INSERT INTO schedules (id, start_date, end_date) VALUES (1, '2017-06-01', '2017-06-30');
INSERT INTO days (id, schedule_id, wday) VALUES (1, 1, 0);
INSERT INTO time_slots (id, start_time, end_time, day_id) VALUES (1, '18:00', '19:00', 1);
答案 0 :(得分:2)
select s.id, wday, start_date + g calendar_date
from schedules s
cross join generate_series(0, end_date - start_date) g
join days d on d.schedule_id = s.id
where extract(isodow from start_date + g) - 1 = wday
http://rextester.com/GTPQ53700
注意:
generate_series()
您可以生成行,而数据库中没有数据0
表示)。与PostgreSQL最接近的是ISODOW
,但周一至周日使用1-7。 (DOW
,另一方面,周日至周一使用0-6:所以周日从周日开始DOW
。)这实际上并没有考虑time_slots
。如果需要,请将以下谓词添加到WHERE
子句中:
and exists(select 1 from time_slots t where t.day_id = d.id)