2009-06-26 25 views
22

私はデータベースを持っています。私はユーザーベースの成長に基づいてグラフを作成したいと思います。私が今持っているクエリは次のとおりです。これは私が何をしたいほとんどを返しMySQL:レコードがなくても範囲内のすべての日付を選択

SELECT DATE(datecreated), count(*) AS number FROM users 
WHERE DATE(datecreated) > '2009-06-21' AND DATE(datecreated) <= DATE(NOW()) 
GROUP BY DATE(datecreated) ORDER BY datecreated ASC 

。 1日に0人のユーザーを取得した場合、その日は0の値として返されず、スキップされ、少なくとも1人のユーザーを含む翌日が返されます。どのように私は(疑似応答)のようなものを得ることができます:ゼロの日付は、日付の残りの部分と順番に表示

date1 5 
date2 8 
date3 0 
date4 0 
date5 9 
etc... 

ありがとうございます!

答えて

5

This questionと私は同じと思います。一般に受け入れられる答えは、あなたがアプリケーションロジック(配列に何を持っているかを読んでから、配列をループして欠落した日付を作成する)、またはあなたが望む日付でいっぱいの一時テーブルを使用する参加する。

1

テーブルに右外部結合を行います。レポートを作成する日付があらかじめ入力されているtblCalendarとしてください。日付フィールドに参加します。

ポール

0

さらに考えでは、このようなものは、あなたが望むものでなければなりません:

CREATE TEMPORARY TABLE DateSummary1 (datenew timestamp) SELECT DISTINCT(DATE(datecreated)) as datenew FROM users; 

CREATE TEMPORARY TABLE DateSummary2 (datenew timestamp, number int) SELECT DATE(datecreated) as datenew, count(*) AS number FROM users 
WHERE DATE(datecreated) > '2009-06-21' AND DATE(datecreated) <= DATE(NOW()) 
GROUP BY DATE(datecreated) ORDER BY datecreated ASC; 

SELECT ds1.datenew,ds2.number FROM DateSummary1 ds1 LEFT JOIN DateSummary2 ds2 on ds1.datenew=ds2.datenew; 

は、これはあなたにすべての最初のテーブルの日付、および第二の表のcount要約データを提供します。 ds2.numberIF(ISNULL(ds2.number),0,ds2.number)などと置き換える必要があります。

13

残りの部分を把握していただければ幸いです。

select n3.num*100+n2.num*10+n1.num as date 

select * from (
select date_add('2003-01-01 00:00:00.000', INTERVAL n5.num*10000+n4.num*1000+n3.num*100+n2.num*10+n1.num DAY) as date from 
(select 0 as num 
    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, 
(select 0 as num 
    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, 
(select 0 as num 
    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, 
(select 0 as num 
    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) n4, 
(select 0 as num 
    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) n5 
) a 
where date >'2011-01-02 00:00:00.000' and date < NOW() 
order by date 

あなたは私たちがここにいるので100 + MAX(N2)* 10 + MAX(N1)

* 0から最大までの番号を持つカラム(N3)を取得しますmax n3が3の場合、SELECTは399、さらに0〜400のレコード(カレンダーの日付)を返します。

ダイナミックカレンダーを調整するには、たとえばmin(date)からnow()に変更するなどの方法があります。

+0

これは素晴らしいテクニックだと思います。私の投票を取得します。このクエリを使用して "カレンダー"テーブルを作成することができます。 –

+0

これは私がこの問題で見た最もクリーンな解決策です。すばらしい –

0

クエリは次のとおりです。

SELECT qb.dy as yourday, COALESCE(count(yourcolumn), 0) as yourcount from yourtable qa 
right join (
    select curdate() as dy union 
    select DATE_SUB(curdate(), INTERVAL 1 day) as dy  union 
    select DATE_SUB(curdate(), INTERVAL 2 day) as dy  union 
    select DATE_SUB(curdate(), INTERVAL 3 day) as dy  union 
    select DATE_SUB(curdate(), INTERVAL 4 day) as dy  union 
    select DATE_SUB(curdate(), INTERVAL 5 day) as dy  union 
    select DATE_SUB(curdate(), INTERVAL 6 day) as dy   
    ) as qb 
on qa.dates = qb.dy 
and qa.dates > DATE_SUB(curdate(), INTERVAL 7 day) 
order by qb.dy asc; 

と結果は次のとおりです。

+------------+-----------+ 
| yourday | yourcount | 
+------------+-----------+ 
| 2015-06-24 | 274339 | 
| 2015-06-25 |  0 | 
| 2015-06-26 |  0 | 
| 2015-06-27 |  0 | 
| 2015-06-28 | 134703 | 
| 2015-06-29 | 87613 | 
| 2015-06-30 |  0 | 
+------------+-----------+ 
4

これはと行う方が良いです:

-- 7 Days: 
set @n:=date(now() + interval 1 day); 
SELECT qb.day_series as days , COALESCE(col_byte, 0) as Bytes from tbl1 qa 
    right join (
     select (select @n:= @n - interval 1 day) day_series from tbl1 limit 7) as qb 
    on date(qa.Timestamp) = qb.day_series and 
qa.Timestamp > DATE_SUB(curdate(), INTERVAL 7 day) order by qb.day_series asc 

-- 30 Days: 
set @n:=date(now() + interval 1 day); 
SELECT qb.day_series as days , COALESCE(col_byte, 0) as Bytes from tbl1 qa 
    right join (
     select (select @n:= @n - interval 1 day) day_series from tbl1 limit 30) as qb 
    on date(qa.Timestamp) = qb.day_series and 
qa.Timestamp > DATE_SUB(curdate(), INTERVAL 30 day) order by qb.day_series asc; 

またはこのような変数なし:

SELECT qb.day_series as days , COALESCE(col_byte, 0) as Bytes from tbl1 qa 
right join (
    select curdate() - INTERVAL a.a day as day_series 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 
    ) as a) as qb 
on date(qa.Timestamp) = qb.day_series and 
qa.Timestamp > DATE_SUB(curdate(), INTERVAL 7 day) order by qb.day_series asc; 
+0

この回答を受け入れてください! – alijunior

関連する問題