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

データベースから返された日付のギャップを埋める-純粋なSQLソリューションは可能ですか?

    はい、0から999までの数値のみを含む数値テーブル(単一列N)を作成することをお勧めします。これは、以下のようなクエリなど、さまざまな用途に使用できます。

    SELECT COUNT(t.click_date) as clicks,
        DATE_FORMAT(adddate($start_date, interval N day), '%d %M %Y') as point 
    FROM Numbers
    LEFT JOIN tracking t
        ON t.click_date >= adddate($start_date, interval N day)
        and t.click_date < adddate($start_date, interval (N+1) day)
    WHERE N between 0 and datediff($start_date, $end_date)
    GROUP BY N
    

    間違った形式を使用しています。大文字の場合Wは曜日によって低くならないため、'%W%M%Y' または'%d%M%Y' 月の日。 http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_date-format

    GROUP BY DAY(FROM_UNIXTIME(click_date))を使用しています 「日」に注意してください 平日ではありませんが、 "%W" を表示しています(または表示しようとしています)。 (平日)-1つ選んでください。混ぜないでください。

    編集: Numbersシーケンステーブルを実体化(実際のテーブルとして作成)したくない場合は、その場で作成できます。かわいくないでしょう。

    注:以下のN1、N2、およびN3を組み合わせて、0〜999の可能な範囲を提供します

    SELECT COUNT(t.click_date) as clicks,
        DATE_FORMAT(adddate($start_date, interval N day), '%d %M %Y') as point 
    FROM (
        select N1 * 100 + N2 * 10 + N3 as N
        from (
        select 0 N1 union all select 1 union all select 2 union all
        select 3 union all select 4 union all select 5 union all
        select 6 union all select 7 union all
        select 8 union all select 9) N1
        cross join (
        select 0 N2 union all select 1 union all select 2 union all
        select 3 union all select 4 union all select 5 union all
        select 6 union all select 7 union all
        select 8 union all select 9) N2
        cross join (
        select 0 N3 union all select 1 union all select 2 union all
        select 3 union all select 4 union all select 5 union all
        select 6 union all select 7 union all
        select 8 union all select 9) N3
        ) Numbers
    LEFT JOIN tracking t
        ON t.click_date >= adddate($start_date, interval N day)
        and t.click_date < adddate($start_date, interval (N+1) day)
    WHERE N between 0 and datediff($start_date, $end_date)
    GROUP BY N
    

    編集#2: まっすぐな日付テーブル

    これをphpMyAdminの新しいウィンドウに配置するか、バッチとして実行します。 1900-01-01日からのすべての日付を含むDatesという名前のテーブルを作成します (またはスクリプトを変更して)2300-01-01に変更します (または変更)。

    DROP PROCEDURE IF EXISTS FillDateTable;
    
    delimiter //
    CREATE PROCEDURE FillDateTable()
        LANGUAGE SQL
        NOT DETERMINISTIC
        CONTAINS SQL
        SQL SECURITY DEFINER
        COMMENT ''
    BEGIN
      drop table if exists datetable;
      create table datetable (thedate datetime primary key, isweekday smallint);
    
      SET @x := date('1900-01-01');
      REPEAT 
        insert into datetable (thedate, isweekday) SELECT @x, case when dayofweek(@x) in (1,7) then 0 else 1 end;
        SET @x := date_add(@x, interval 1 day);
        UNTIL @x > date('2300-01-01') END REPEAT;
    END//
    delimiter ;
    
    CALL FillDateTable;
    

    このようなユーティリティテーブルを使用すると、クエリを実行できます

    SELECT COUNT(t.click_date) as clicks,
        DATE_FORMAT(thedate, '%d %M %Y') as point 
    FROM Dates
    LEFT JOIN tracking t
        ON t.click_date >= thedate
        and t.click_date < adddate(thedate, interval 1 day)
    WHERE thedate between $start_date and $end_date
    GROUP BY thedate
    


    1. mysqlは同じnow()で複数の列を更新します

    2. OracleDatabaseでサポートされている言語のリスト

    3. SCDタイプ1

    4. SQLServerのカーソルタイプ-SQLServerの静的カーソルとは| SQLServerチュートリアル/TSQLチュートリアル