このディレクトリの索引

# 出典 :: SQL質疑応答スレ 10問目 #139 # 期間の抽出について相談です。 # 元情報 # ID    START    END # -----   -----    ----- # 10    2010/06/01  2010/06/12 # 10    2010/06/13  2010/06/14 # 10    2010/06/15  NULL # 20    2010/06/01  2010/06/11 # 20    2010/06/13  2010/06/15 # ↓ # 欲しい情報 # ID    START    END # -----   -----    ----- # 10    2010/06/01  NULL # 20    2010/06/01  2010/06/11 # 20    2010/06/13  2010/06/15 # # ・開始日、終了日の期間重複はなし # ・IDごとにデータを抽出。抽出単位は連続している期間の最小開始日と最大終了日 # ・期間は綺麗に連続(ID=10)することもあれば非連続することもある(ID=20) # # アドバイス願います。 # # 期間(10,2010/06/01,2010/06/12). 期間(10,2010/06/13,2010/06/14). 期間(10,2010/06/15,9999/99/99). 期間(20,2010/06/01,2010/06/11). 期間(20,2010/06/13,2010/06/15). 'IDごとにデータを抽出。抽出単位は連続している期間の最小開始日と最大終了日を表示する' :- 'IDごとにデータを抽出。抽出単位は連続している期間の最小開始日と最大終了日'(L), 表示する(L). 'IDごとにデータを抽出。抽出単位は連続している期間の最小開始日と最大終了日'(L) :- setof(_ID,[_ID,_期間下限,_期間上限] ^ 期間(_ID,_期間下限,_期間上限),L1), findall([_ID,_連続期間の最小開始日,_連続期間の最大終了日],( 'IDごとにデータを抽出。抽出単位は連続している期間の最小開始日と最大終了日'(L1,_ID,_連続期間の最小開始日,_連続期間の最大終了日)),L). 'IDごとにデータを抽出。抽出単位は連続している期間の最小開始日と最大終了日'(L1,_ID,_連続期間の最小開始日,_連続期間の最大終了日) :- member(_ID,L1), 連続している期間の最小開始日と最大終了日(_ID,L1,_連続期間の最小開始日,_連続期間の最大終了日). 連続している期間の最小開始日と最大終了日(_ID,[[_ID,_最小開始日_1,_最大終了日_1],[_ID,_最小開始日_2,_最大終了日_2]|R],X,Y) :- 連続日(_最大終了日_1,_,_最小開始日_2,_), 連続している期間の最小開始日と最大終了日(_ID,[[_ID,_最小開始日_1,_最大終了日_2]|R],X,Y),!. 連続している期間の最小開始日と最大終了日(_ID,[[_ID,_最小開始日_1,_最大終了日_1],[_ID,_最小開始日_2,_最大終了日_2]|R],_最小開始日_1,_最大終了日_1) :- \+(連続日(_最大終了日_1,_,_最小開始日_2,_)). 連続している期間の最小開始日と最大終了日(_ID,[[_ID,_最小開始日_1,_最大終了日_1],[_ID,_最小開始日_2,_最大終了日_2]|R],_最小開始日_1,_最大終了日_1) :- \+(連続日(_最大終了日_1,_,_最小開始日_2,_)), 連続している期間の最小開始日と最大終了日(_ID,[[_ID,_最小開始日_2,_最大終了日_2]|R],X,Y),!. 連続している期間の最小開始日と最大終了日(_ID,[[_ID,_最小開始日,_最大終了日]|R],_最小開始日,_最大開始日). 表示する(L) :- write('ID START END \n----- ----- ----- \n'), forall(member([_ID,_Start,_End],L),writef('%w %w %w\n',[_ID,_Start,_End])). 開始日(_ID,_開始日) :- 期間(_ID,_開始日,_). 終了日(_ID,_終了日) :- 期間(_ID,_開始日,_終了日),\+(_終了日='NULL'). 日付曜日を遡る(_今日,_今日の曜日,_遡った日付,_遡った曜日) :- 連続日(_前日,_前日の曜日,_今日,_今日の曜日), 前日から更に遡る(_前日,_前日の曜日,_遡った日付,_遡った曜日). 前日から更に遡る(_遡った日付,_遡った曜日,_遡った日付,_遡った曜日). 前日から更に遡る(_前日,_前日の曜日,_遡った日付,_遡った曜日) :- 日付曜日を遡る(_前日,_前日の曜日,_遡った日付,_遡った曜日). 連続日(_前の日の年/_前の日の月/_前の日の日,_前の日の曜日,_後の日の年/_後の日の月/_後の日の日,_後の日の曜日) :- 翌日(_前の日の年,_前の日の月,_前の日の日,_後の日の年,_後の日の月,_後の日の日), 曜日連鎖(_前の日の曜日,_後の日の曜日). 翌日(_年,12,31,_翌日の年,1,1) :- succ(_年,_翌日の年),!. 翌日(_年,2,29,_年,3,1) :- うるう年(_年),!. 翌日(_年,2,28,_年,3,1) :- \+(うるう年(_年)),!. 翌日(_年,_月,_日,_年,_翌日の月,1) :- succ(_月,_翌日の月),'十二月・二月を除く月末日'(_月,_日),!. 翌日(_年,_月,_日,_年,_月,_翌日の日) :- succ(_日,_翌日の日). '十二月・二月を除く月末日'(_月,30) :- 小の月(_月). '十二月・二月を除く月末日'(_月,31) :- 大の月(_月). 小の月(2). 小の月(4). 小の月(6). 小の月(9). 小の月(11). 大の月(1). 大の月(3). 大の月(5). 大の月(7). 大の月(8). 大の月(10). 大の月(12). うるう年(_年) :- 0 is _年 mod 400,!. うるう年(_年) :- 0 is _年 mod 100,!,fail. うるう年(_年) :- 0 is _年 mod 4. 曜日連鎖(日曜,月曜). 曜日連鎖(月曜,火曜). 曜日連鎖(火曜,水曜). 曜日連鎖(水曜,木曜). 曜日連鎖(木曜,金曜). 曜日連鎖(金曜,土曜). 曜日連鎖(土曜,日曜).