これを行う1つの方法は、相関サブクエリを使用することです。
SELECT DISTINCT
(SELECT MIN(opens)
FROM mytable AS t2
WHERE t2.opens <= t1.closes AND t2.closes >= t1.opens) AS start,
(SELECT MAX(closes)
FROM mytable AS t2
WHERE t2.opens <= t1.closes AND t2.closes >= t1.opens) AS end
FROM mytable AS t1
ORDER BY opens
WHERE
相関サブクエリの述語:
t2.opens <= t1.closes AND t2.closes >= t1.opens
現在のレコードに関連するすべての重複レコードを返します。これらのレコードの集計を実行すると、各間隔の開始日/終了日を見つけることができます。間隔の開始日は、最小のopens
です。 重複するすべてのレコード間の日付。終了日は最大のcloses
日付。
編集:
上記のソリューションは、次のような一連の間隔では機能しません。
1. |-----------|
2. |----|
3. |-----|
レコード番号2、処理されると、欠陥のある開始/終了間隔が生成されます。
変数を使用した解決策は次のとおりです。
SELECT MIN(start) AS start, MAX(end) AS end
FROM (
SELECT @grp := IF(@start = '1900-01-01' OR
(opens <= @end AND closes >= @start), @grp, @grp+1) AS grp,
@start := IF(@start = '1900-01-01', opens,
IF(opens <= @end AND closes >= @start,
IF (@start < opens, @start, opens), opens)) AS start,
@end := IF(@end = '1900-01-01', closes,
IF (opens <= @end AND closes >= @start,
IF (@end > closes, @end, closes), closes)) AS end
FROM mytable
CROSS JOIN (SELECT @grp := 1, @start := '1900-01-01', @end := '1900-01-01') AS vars
ORDER BY opens, DATEDIFF(closes, opens) DESC) AS t
GROUP BY grp
アイデアは、左端のopens/closes
から開始することです。 間隔。変数@start
、@end
(新しい重複行が処理されているときに)段階的に拡張する統合された間隔を間隔チェーンに伝播するために使用されます。重複しない間隔が検出されると、[@start - @end]
この新しい間隔とgrp
に一致するように初期化されます 1ずつ増加します。