2016-07-11 10 views
1

私はテーブル「lessons_holidays」を持っています。それはすなわち、MySQLで重複する日付範囲を結合する方法は?

"holiday_begin" "holiday_end" 
2016-06-15   2016-06-15 
2016-06-12   2016-06-16 
2016-06-15   2016-06-19 
2016-06-29   2016-06-29 

私は日付の範囲が重複する場合は、各項目を組み合わせるしたいと思い、いくつかの休日の日付の範囲を含めることができます。

"holiday_begin" "holiday_end" 
2016-06-12   2016-06-19 
2016-06-29   2016-06-29 

SQL::次のSQL文のロードすべての行と、私はこのような出力を必要としています。今私は立ち往生している。

SELECT lh1.holiday_begin, lh1.holiday_end 
FROM local_lessons_holidays lh1 
WHERE lh1.holiday_impact = '1' AND 
(DATE_FORMAT(lh1.holiday_begin, '%Y-%m') <= '2016-06' AND DATE_FORMAT(lh1.holiday_end, '%Y-%m') >= '2016-06') AND 
lh1.uid = '1' 
+0

これはMySQLでは非常に困難です。他にもデータベースがありますか? –

答えて

2

これは難しい問題です。これは、MySQLを使用しているため難しくなっています。ここに考えがあります。各グループのすべての休暇の開始日を検索します。次に、「開始」のフラグの累積合計がグループを処理します。残りは単なる集合体です。ちょうどテーブルに最も内側の参照にselect distinctを使用し、あなたが重複している場合は

select min(holiday_begin) as holiday_begin, max(holiday_end) as holiday_end 
from (select lh.*, (@grp := @grp + group_flag) as grp 
     from (select lh.*, 
        (case when not exists (select 1 
              from lessons_holidays lh2 
              where lh2.holiday_begin <= lh.holiday_end and 
               lh2.holiday_end > lh.holiday_begin and 
               (lh2.holiday_begin <> lh.holiday_begin or 
               lh2.holiday_end < lh.holiday_end) 

             ) 
         then 1 else 0 
        end) as group_flag 
      from lessons_holidays lh 
      ) lh cross join 
      (select @grp := 0) params 
     order by holiday_begin, holiday_end 
    ) lh 
group by grp; 

は次のようにあなたは何の重複レコードを持っていないと仮定すると、あなたが欲しいものを行う必要があります。

HereはSQL Fiddleです。

EDIT:

このバージョンでは、より良い仕事に表示されます:hereを示す

select min(holiday_begin) as holiday_begin, max(holiday_end) as holiday_end 
from (select lh.*, (@grp := @grp + group_flag) as grp 
     from (select lh.*, 
        (case when not exists (select 1 
              from lessons_holidays lh2 
              where lh2.holiday_begin <= lh.holiday_begin and 
               lh2.holiday_end > lh.holiday_begin and 
               lh2.holiday_begin <> lh.holiday_begin and 
               lh2.holiday_end <> lh.holiday_end 
             ) 
         then 1 else 0 
        end) as group_flag 
      from lessons_holidays lh 
      ) lh cross join 
      (select @grp := 0) params 
     order by holiday_begin, holiday_end 
    ) lh 
group by grp; 

通り。

+0

ありがとうございます。私は後で試してみる。 – Bonaparte

+0

結果として私は次のようになります:2016-06-12 | 2016年6月29日。この結果は、次のSQL文によっても取得できます。 "SELECT MIN(holiday_begin)as holiday_begin、MAX(holiday_end)as holiday_end FROM local_lessons_holidays WHERE 1" – Bonaparte

+0

@Bonaparte。 。 。一定。問題はオーバーラップロジックでした。 –

関連する問題