sql >> データベース >  >> RDS >> Mysql

日付スパンが重複するMySQL統合テーブル行

    これを行う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ずつ増加します。

    デモはこちら




    1. MySQLのGroupByとの1対多結合は、1つの観測値のみを返します

    2. SQLスクリプトを検証するためのコード

    3. Hibernatehbm2ddl.autoのデフォルト値

    4. MySQLのリレーショナルテーブルにExcelデータをインポートする