sql - 如何返回带有基于星期几的日历日期的记录?

标签 sql postgresql

我有以下架构:

时间表代表重复事件的时间表。

# Table name: schedules
#
#  id         :integer          not null, primary key
#  start_date :date
#  end_date   :date

天数表示事件发生的时间表的工作日。

# Table name: days
#
#  id          :integer          not null, primary key
#  schedule_id :integer
#  wday        :integer

时间段表示事件可能发生的时间(每天可能有多个)。

# Table name: time_slots
#
#  id           :integer          not null, primary key
#  day_id       :integer
#  start_time   :time             not null
#  end_time     :time             not null

示例数据集可能是:

  • 1 个时间表,开始日期为 6 月 1 日,结束日期为 6 月 30 日
  • 1 天,宽度 wday = 0(事件发生在六月的每周一)
  • 2 个时间段。 1,开始时间为上午 8 点,结束时间为上午 11 点。另一种时间为下午 1 点开始时间和下午 3 点结束时间

鉴于上面的示例(在下面的 SQL 中表示),我想返回 6 月每个星期一的一条记录,并包含其日历日期。

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);

最佳答案

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)
    

关于sql - 如何返回带有基于星期几的日历日期的记录?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43096240/

相关文章:

python - 如何将默认值数组添加到 ArrayField?

java - 如何使用 JPA 实体构建和填充数据库?

ruby-on-rails - 通过 capistrano 部署安装 pg 时出错

sql - 有没有办法将 JSON 对象数组与其他 View /表中的另一个 JSON 对象数组合并?

ruby - 在 n 为 :m relation 的表中为每个用户创建唯一约束

javascript - 如何改进cubejs预聚合创建过程? (即使使用partitionGranularity,构建预聚合也需要很长时间)

sql - 在 SQL Server 2012 中选择逗号分隔值

sql - 'JSON' 附近的语法不正确 - SQL Server 2014

MySQL:将连接后的多个值组合到一个结果列中

sql 到 postgresql