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

間隔で動的な年と月を使用して、連続してゼロを表示するにはどうすればよいですか?

    素敵なパズル:)

    12か月の間隔に必要な年と月を保持するテーブルを生成してから、そのテーブルで外部結合を実行できます:

    SET @var_year = '2013'
    SET @var_month = '12'
    
    SELECT @row := @row + (case when right(@row,2) = "12" then 89 else 1 end) as YearMonth 
    FROM 
    (select 0 union all select 1 union all select 3 union all 
     select 4 union all select 5 union all select 6 union all 
     select 6 union all select 7 union all select 8 union all 
     select 9 union all select 10 union all select 11) t,
    (SELECT @row:=CONCAT(@var_year,right(concat('0',(@var_month-1)),2))) r
    

    与える:

    | YearMonth |
    |-----------|
    |    201312 |
    |    201401 |
    |    201402 |
    |    201403 |
    |    201404 |
    |    201405 |
    |    201406 |
    |    201407 |
    |    201408 |
    |    201409 |
    |    201410 |
    |    201411 |
    

    だからこれを試してみてください(2014年を年、1を月とする例):

    SQLフィドル

    MySQL5.5スキーマのセットアップ

    CREATE TABLE creations(`id` int, `created_at` date )
    ;
    
    INSERT INTO creations
        (`id`, `created_at`)
    VALUES
        (1, '2013-12-11'),
        (2, '2014-01-11'),
        (3, '2014-01-21'),
        (4, '2014-01-12'),
        (5, '2014-02-22'),    
        (6, '2014-02-13'),
        (7, '2014-03-12'),    
        (8, '2014-04-23'),
        (9, '2014-05-23'),
        (10,'2014-06-23'),
        (11,'2014-08-23'),    
        (12,'2014-08-23'),
        (13,'2014-09-23'),
        (14,'2014-10-23'),    
        (15,'2014-11-23'),        
        (16,'2014-12-23')         
    ;
    

    **クエリ**:

    SET @var_year = '2014'
    SET @var_month = '1'
    
    SELECT count(created_at) AS count_all,
           left(YearMonth,4) as actual_year,
           right(YearMonth,2) as actual_month 
    FROM (
    SELECT @row := @row + (case when right(@row,2) = "12" then 89 else 1 end) as YearMonth FROM 
    (select 0 union all select 1 union all select 3 union all 
     select 4 union all select 5 union all select 6 union all 
     select 6 union all select 7 union all select 8 union all 
     select 9 union all select 10 union all select 11) t,
    (SELECT @row:=CONCAT(@var_year,right(concat('0',(@var_month-1)),2))) r
    ) as YearMonthTable
    LEFT OUTER JOIN creations ON
      CONCAT(year(created_at),right(concat('0',month(created_at)),2)) = YearMonth
    GROUP BY YearMonth
    ORDER BY YearMonth ASC
    

    結果

    | count_all | actual_year | actual_month |
    |-----------|-------------|--------------|
    |         3 |        2014 |           01 |
    |         2 |        2014 |           02 |
    |         1 |        2014 |           03 |
    |         1 |        2014 |           04 |
    |         1 |        2014 |           05 |
    |         1 |        2014 |           06 |
    |         0 |        2014 |           07 |
    |         2 |        2014 |           08 |
    |         1 |        2014 |           09 |
    |         1 |        2014 |           10 |
    |         1 |        2014 |           11 |
    |         1 |        2014 |           12 |
    

    編集済み:

    毎回サブクエリでテーブルを生成する代わりに、テーブルを作成することもできます:

    SQLフィドル

    MySQL5.5スキーマのセットアップ

    CREATE TABLE YearMonthTable(`tblYear` int, `tblMonth` int)
    ;
    
    INSERT INTO YearMonthTable
        (`tblYear`,`tblMonth`)
    VALUES
        (2013,12),
        (2014,1),
        (2014,2),    
        (2014,3),    
        (2014,4),
        (2014,5),
        (2014,6),
        (2014,7),    
        (2014,8),
        (2014,9),
        (2014,10),    
        (2014,11),        
        (2014,12),
        (2015,1),
        (2015,2),    
        (2015,3),    
        (2015,4),
        (2015,5)
    ;
    

    クエリ

    SET @var_year = '2014'
    SET @var_month = '1'
    
    SET @from = STR_TO_DATE(CONCAT(@var_year, '/', @var_month, '/01'), '%Y/%m/%d')
    SET @to = DATE_ADD(DATE_ADD(@from, INTERVAL 12 MONTH), INTERVAL -1 DAY)
    
    SELECT count(created_at) AS count_all,
           tblYear as actual_year,
           tblMonth as actual_month 
    FROM YearMonthTable
    LEFT OUTER JOIN creations ON year(created_at) = tblYear AND 
                                 month(created_at) = tblMonth
    WHERE STR_TO_DATE(CONCAT(tblYear, '/', tblMonth, '/01'), '%Y/%m/%d') 
                                                        BETWEEN @from AND @to                               
    GROUP BY tblMonth, tblYear
    ORDER BY tblYear, tblMonth
    

    結果

    | count_all | tblYear | tblMonth |
    |-----------|---------|----------|
    |         3 |    2014 |        1 |
    |         2 |    2014 |        2 |
    |         1 |    2014 |        3 |
    |         1 |    2014 |        4 |
    |         1 |    2014 |        5 |
    |         1 |    2014 |        6 |
    |         0 |    2014 |        7 |
    |         2 |    2014 |        8 |
    |         1 |    2014 |        9 |
    |         1 |    2014 |       10 |
    |         1 |    2014 |       11 |
    |         1 |    2014 |       12 |
    



    1. 線形回帰、MySQLで勾配を見つける

    2. グループなしでカウント

    3. mysqlでINDEXESを使用する最大の利点は何ですか?

    4. SELECT句で複数のセットを返す関数に期待される動作は何ですか?