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

2つ以上の日付範囲を1つにマージする方法

    ここに、ユーザー変数を使用したソリューションがあります。ご提供いただいたデータで確認しました。確認のためにさらにデータを挿入しました。

    クエリ結果を永続的に保存し、後でアクセスできるようにするために、結果はテーブルtbl_newに書き込まれます。

    完全なデモ>>

    SQL:

    -- data preparation
    create table tbl(acct varchar(100), start_date date, end_date date);
    insert into tbl values
    ('Acct-1', '2016-01-01', '2016-01-07'),
    ('Acct-1', '2016-01-05', '2016-01-11'),
    ('Acct-1', '2016-01-18', '2016-01-24'),
    ('Acct-1', '2016-02-02', '2016-02-08'),
    ('Acct-1', '2016-02-07', '2016-02-13'),
    ('Acct-2', '2016-01-01', '2016-01-07'),
    ('Acct-2', '2016-01-18', '2016-01-24'),
    ('Acct-2', '2016-01-02', '2016-02-08');
    
    
    SELECT * FROM tbl;
    
    -- Need queries
    SET @last_acct = '', @last_start_date = '1970-01-01', @last_end_date = '9999-12-31', @group = 1;
    
    CREATE TABLE tbl_new (acct varchar(100), start_date date, end_date date);
    
    INSERT INTO tbl_new 
    SELECT 
        acct,
        MIN(start_date) start_date,
        MAX(end_date) end_date
    FROM
    (
        SELECT
            acct, 
            start_date, 
            end_date,
            CASE 
                WHEN 
                    acct = @last_acct AND start_date <= @last_end_date 
                THEN 
                    @group
                ELSE
                    @group := @group + 1
            END group_num, 
            @last_acct := acct,
            @last_start_date := start_date,
            @last_end_date := end_date
        FROM
            tbl
    ) tbl2
    GROUP BY group_num;
    
    SELECT * FROM tbl_new;
    

    出力:

    mysql> SELECT * FROM tbl;
    +--------+------------+------------+
    | acct   | start_date | end_date   |
    +--------+------------+------------+
    | Acct-1 | 2016-01-01 | 2016-01-07 |
    | Acct-1 | 2016-01-05 | 2016-01-11 |
    | Acct-1 | 2016-01-18 | 2016-01-24 |
    | Acct-1 | 2016-02-02 | 2016-02-08 |
    | Acct-1 | 2016-02-07 | 2016-02-13 |
    | Acct-2 | 2016-01-01 | 2016-01-07 |
    | Acct-2 | 2016-01-18 | 2016-01-24 |
    | Acct-2 | 2016-01-02 | 2016-02-08 |
    +--------+------------+------------+
    8 rows in set (0.00 sec)
    
    mysql>
    mysql> -- Need queries
    mysql> SET @last_acct = '', @last_start_date = '1970-01-01', @last_end_date = '9999-12-31', @group = 1;
    Query OK, 0 rows affected (0.00 sec)
    
    mysql>
    mysql> CREATE TABLE tbl_new (acct varchar(100), start_date date, end_date date);
    Query OK, 0 rows affected (0.01 sec)
    
    mysql>
    mysql> INSERT INTO tbl_new
        -> SELECT
        ->     acct,
        ->     MIN(start_date) start_date,
        ->     MAX(end_date) end_date
        -> FROM
        -> (
        ->     SELECT
        ->         acct,
        ->         start_date,
        ->         end_date,
        ->         CASE
        ->             WHEN
        ->                 acct = @last_acct AND start_date <= @last_end_date
        ->             THEN
        ->                 @group
        ->             ELSE
        ->                 @group := @group + 1
        ->         END group_num,
        ->         @last_acct := acct,
        ->         @last_start_date := start_date,
        ->         @last_end_date := end_date
        ->     FROM
        ->         tbl
        -> ) tbl2
        -> GROUP BY group_num;
    
    Query OK, 5 rows affected (0.00 sec)
    Records: 5  Duplicates: 0  Warnings: 0
    
    mysql>
    mysql> SELECT * FROM tbl_new;
    +--------+------------+------------+
    | acct   | start_date | end_date   |
    +--------+------------+------------+
    | Acct-1 | 2016-01-01 | 2016-01-11 |
    | Acct-1 | 2016-01-18 | 2016-01-24 |
    | Acct-1 | 2016-02-02 | 2016-02-13 |
    | Acct-2 | 2016-01-01 | 2016-01-07 |
    | Acct-2 | 2016-01-02 | 2016-02-08 |
    +--------+------------+------------+
    5 rows in set (0.00 sec)
    



    1. MySQLタイムスタンプからJava日付への変換

    2. CONCAT_WS()がPostgreSQLでどのように機能するか

    3. MySQLのインデックスを理解する:パート3

    4. 非同期呼び出しをまとめて同期的に動作させるにはどうすればよいですか?