

以下のSQLで集計を行おうとしておりますが、要件として売り上げがない日(0円)の データも出力したいのですが、どのようにするのがよいでしょうか？
できれば、データベース側で完結したいです。

[code]

    2014/12/1 ¥10000
    2014/12/2 ¥10000
    2014/12/3  ＊このレコードは存在していないですが、リストで　2014/12/3 ¥0と出力したい。
    2014/12/4 ¥10000
    
[/code]

sql

[code]

    select
        DATE_FORMAT(s.start_date, '%Y-%m-%d') as date,
        sum(p.price) as price
    from
        sales s
    inner join
        products p
    on
        s.product_id = p.id     
    group by
        DATE_FORMAT(s.start_date, '%Y%m%d');
    
[/code]


CC BY-SA 3.0
2014-12-27T02:46:41.007
2667
2014-12-27T05:33:04.427
2014-12-27T02:52:59.437
728
4496
question
mysql sql
Mysqlでの集計について


すいません、最初の回答は勘違いしていました。

salesの方にない日付も出力したいということですね。

日付テーブルを別途用意するしかないかと思います。

* * *

[**本家の方で同様の質問**](https://stackoverflow.com/questions/2157282/generate-days-
from-date-range)があり、以下で日付テーブルを生成できるようです。

ループも一時表も使わずに生成しています。  
ただし、curdateを使っている関係からか、古い日付だと取得できないことがあるようです。  
（私の環境ですと2011年だと結果が空に）。

[code]

    select a.Date 
    from (
        select curdate() - INTERVAL (a.a + (10 * b.a) + (100 * c.a)) DAY as Date
        from (select 0 as a 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) as a
        cross join (select 0 as a 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) as b
        cross join (select 0 as a 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) as c
    ) a
    where a.Date between '2014-12-20' and '2014-12-27' 
    
[/code]

* * *

都度作成では問題になる場合（パフォーマンスまたはSQLの見た目の問題など）のために、  
カレンダーテーブルを作成するプロシージャのサンプルを作成してみました。(mysql 5.1.59)

以下の様なテーブルに、年と日付を指定してその月の日付を投入します。  
day列は数値ではなくdatetimeであることに注意してください。

[code]

    create table mycalendar (year integer, month integer, day datetime) 
    
[/code]

後で示しているプロシージャを作成後、年月を指定して呼び出すと mycalendar テーブルにデータを投入します。

[code]

    call sampleInsertDaysToMyCalendar(2010,2)
    
[/code]

コメントで書いていますが、3行入れ替えると月の指定を無視して 1年分のテーブル作成に変更できます。

テーブルとプロシージャの作成を一気に行うコードは以下の通り（データの投入はコメントアウトしています。）。  
phpmyadminで実行できることを確認しています。

[code]

    delimiter //
    
    -- テーブルが無ければ作成します。
    create table if not exists mycalendar (year integer, month integer, day datetime) 
    //
    
    -- プロシージャが存在すれば削除します。
    drop procedure if exists sampleInsertDaysToMyCalendar
    //
    
    -- プロシージャの作成部分です。
    CREATE PROCEDURE sampleInsertDaysToMyCalendar(IN _year integer, IN _month integer)
    BEGIN
      set @curday = date_add(makedate(_year,1), interval (_month)-1 month);
      set @lastday = last_day(@curday);
    
      delete from mycalendar where year = _year and month = _month;
    
      -- 月を無視して、年のデータを入れたい場合、上の3行と下のコメントアウトしている3行を入れ替えます。
      -- set @curday = makedate(_year,1);
      -- set @lastday = last_day(date_add(@curday, interval (12)-1 month));
      -- delete from mycalendar where year = _year;  
    
      commit;
    
      while @curday <= @lastday do
         insert into mycalendar (year, month, day) values (_year, _month, @curday);
         set @curday = ADDDATE(@curday, 1);
      end while;
      commit;
    
    END
    //
    
    
    -- プロシージャを実行します。
    -- call sampleInsertDaysToMyCalendar(2010,2) //
    
    -- デリミタを ;に。
    delimiter ;
    
[/code]


CC BY-SA 3.0
2014-12-27T02:54:10.977
2668
2014-12-27T05:33:04.427
2017-05-23T12:38:56.083
-1
728
2667
answer