web-dev-qa-db-ja.com

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

これはほぼ私が欲しいものを返します。ある日0ユーザーを取得した場合、その日は0値として返されず、スキップされ、少なくとも1人のユーザーがいる次の日に返されます。 (psuedo-response)のようなものを取得するにはどうすればよいですか?

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

ゼロの日付は、残りの日付と順番に表示されますか?

ありがとう!

25
Jason

私はあなたが残りを理解することを願っています。

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

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

0からmax(n3)* 100 + max(n2)* 10 + max(n1)までの数値の列が表示されます

ここでは最大n3が3であるため、SELECTは399に加えて、0-> 400レコード(カレンダーの日付)を返します。

たとえば、min(date)からnow()に制限することで、動的カレンダーを調整できます。

15
Igor Kryltsov

この質問 私が思うのと同じことを尋ねます。一般的に受け入れられている答えは、アプリケーションロジックでそれを行うか(配列にあるものを読み込んでから、配列をループして欠落している日付を作成する)、または希望の日付で満たされた一時テーブルを使用することです。参加します。

5
zombat

これは、次のようにすることをお勧めします。

-- 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;
5
Giac

テーブルへの右外部結合を実行します。これをtblCalendarと呼びます。これには、レポートする日付が事前に入力されています。そして、日付フィールドに参加します。

ポール

1
plitwin

さらに考えてみると、次のようなものが必要です。

_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;
_

これにより、最初のテーブルにすべての日付が表示され、2番目のテーブルにcount要約データが表示されます。 _ds2.number_をIF(ISNULL(ds2.number),0,ds2.number)または同様のものに置き換える必要がある場合があります。

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    |
+------------+-----------+
0
Ganj Khani