36317


いつもお世話になっております。

早速本題ですが、  
スケジュールといったEntityが存在し、その中に睡眠開始時刻と起床時刻(SleepStartTime/SleepEndTime)が保存されています。

このとき、睡眠時間が1:00~4:00の時間帯に重複しないレコードを取得しようとしているのですが、  
中々うまく行きません。  
(not inを使うのかなとは思いいろいろとチャレンジはしているのですが...)

データベースはpostgresqlになります。

以下のイメージになります。(一部抜き出し)  
ScheduleEntity  
id : longintger  
SleepStart :time  
SleepEnd : time

取得したいテーブル例  
id: 1 SleepStart:23:00 SleepEnd:0:30  
id: 2 SleepStart:05:00 SleepEnd:12:30

取得したくないテーブル例  
id: 3 SleepStart:00:00 SleepEnd:03:30  
id: 4 SleepStart:02:00 SleepEnd:08:30  
id: 5 SleepStart:00:30 SleepEnd:09:30

お手数ですが、わかる方教えていただければ幸いです。


CC BY-SA 3.0
2017-07-13T04:05:38.753
36309
2017-07-13T06:59:49.717
20774
question
postgresql
Postgresqlにて指定した範囲の時間を含まないデータを取得したい


PostgreSQL には overlaps がありますので、

[code]

    select * from ScheduleEntity where not (SleepStart, SleepEnd) overlaps (time '1:00', time '4:00');
    
[/code]

とすれば良いはず、、、なのですが、`id:1` の SleepEnd が `0:30` となっていますので抽出できません。

そこで、`SleepStart > SleepEnd` の場合は start と end を逆転して overlap
を検査します。この場合は起きている時間になるので `where (SleepStart, SleepEnd) overlaps ...` になります。

[code]

    create table ScheduleEntity (
      id int,
      SleepStart time,
      SleepEnd time,
      primary key (id)
    );
    
    insert into ScheduleEntity(id, SleepStart, SleepEnd) values (1, '23:00', '0:30');
    insert into ScheduleEntity(id, SleepStart, SleepEnd) values (2, '5:00', '12:30');
    insert into ScheduleEntity(id, SleepStart, SleepEnd) values (3, '0:00', '3:30');
    insert into ScheduleEntity(id, SleepStart, SleepEnd) values (4, '2:00', '8:30');
    insert into ScheduleEntity(id, SleepStart, SleepEnd) values (5, '0:30', '9:30');
    insert into ScheduleEntity(id, SleepStart, SleepEnd) values (6, '22:00', '4:30');
    
    select * from ScheduleEntity
    where
      (SleepStart > SleepEnd and (SleepEnd, SleepStart) overlaps (time '1:00', time '4:00'))
    or
      (SleepStart <= SleepEnd and not (SleepStart, SleepEnd) overlaps (time '1:00', time '4:00'));
    
     id | sleepstart | sleepend 
    ----+------------+----------
      1 | 23:00:00   | 00:30:00
      2 | 05:00:00   | 12:30:00
    
[/code]


CC BY-SA 3.0
2017-07-13T06:46:44.020
36317
2017-07-13T06:59:49.717
2017-07-13T06:59:49.717
36309
answer