2017-12-27 17 views
1

として設定していない場合、私は、次の列を持つテーブルがある:SQL:過去7日間で合計エントリ、日によってグループ、その日のためのエントリが0

id | time (SQL datetime) | url 

私は最後の7日間の合計を取得する必要があります今日から。

その日の合計が0の場合は、まったく返さずに0として返します。

は、私はこれを試してみた:

SELECT 
    time, COUNT(*) AS `num` 
FROM 
    entries 
WHERE 
    time > DATE_SUB(CURDATE(), INTERVAL 7 DAY) 
GROUP BY 
    time 

が、それは私の理解から、時間あたりの合計を返します - 私は何とかこれまでに日時スタンプを変換する必要がありますか?

私はまだSQLを学んでいます。

+0

* *どのSQL? MS SQL Server? MySQL? Postgres?このような単純な質問はおそらくDBMSに依存しないものですが、使用しているDBMSにはまだタグを付ける必要があります。 'CURDATE()の使用は、MySQL、afaictを意味します。 –

答えて

0

これは非常に興味深い質問です。答えは質問よりもはるかに複雑なためです。

通常、SQLは、通常のプログラミング言語と同じように、ループや任意の長さのリストを使用したり、生成物を生成するように設計されていません。一般的に、テーブルにすべてのデータが存在することに依存しています。

すべての日付が既存のテーブルにあれば問題ありません。GROUP BYを使用してください。しかし、どこにテーブルに存在しない日付を取得するには0カウントを表示するには?

SOを見ると、過去にいくつかのオプションが議論され、リストされています。

基本的にはすべての4つの選択肢に沸く:

  • 日付の事前に構築され、必要な範囲での一時的または永続的なテーブルを使用します。すべてのSQLサーバーと互換性がありますが、多少面白いですし、範囲テーブルを更新したままにしておいてください。
  • SQL以外のプログラミング言語で必要な日付のリストを作成し、その後の戻り値を比較します。全くエレガントではありません。
  • サーバーサイドプロシージャを使用します。ポータブルではありませんが、比較的簡単です。プロシージャの引数として指定した間隔の日付を含む行のリストを返すようにします。
  • 変数などの追加のSQLサーバーサイド調整を使用します。あなたのケースでは

、この質問への回答から描画:Get a list of dates between two dates、私は自分自身はあなたのデータテーブルに存在しない日付を含める必要があるため、これはおそらくだろう、しかし、MySQLの変数を使用して検討します(少なくとも私は解決策を見つけることができませんでした)動作しません。

ので、上場問題の解決策のいずれかを使用して、あなたはこのような過去7日の日付、あなたの実際のリストについては、表のようなものを作成する必要があります

temporary table LASTDAYS 
datetime D 
------------- 
2017-12-27 
2017-12-26 
2017-12-25 
2017-12-24 
2017-12-23 
2017-12-22 
2017-12-21 

(注文はここでは重要ではありません)

その後、あなたは:

SELECT DATE(LASTDAYS.D) AS D1, COUNT(YOURTABLE.id) AS num 
FROM LASTDAYS LEFT OUTER JOIN YOURTABLE 
ON DATE(YOURTABLE.time)=date(LASTDAYS.D) 
GROUP BY D1; 

OUTER join注)

しかし、これは本当にブルートフォースされている

CREATE TEMPORARY TABLE LASTDAYS (D datetime); 

INSERT INTO LASTDAYS VALUES (CURRENT_TIMESTAMP); 
INSERT INTO LASTDAYS VALUES (DATE_SUB(CURRENT_TIMESTAMP,INTERVAL 1 DAY)); 
INSERT INTO LASTDAYS VALUES (DATE_SUB(CURRENT_TIMESTAMP,INTERVAL 2 DAY)); 
INSERT INTO LASTDAYS VALUES (DATE_SUB(CURRENT_TIMESTAMP,INTERVAL 3 DAY)); 
INSERT INTO LASTDAYS VALUES (DATE_SUB(CURRENT_TIMESTAMP,INTERVAL 4 DAY)); 
INSERT INTO LASTDAYS VALUES (DATE_SUB(CURRENT_TIMESTAMP,INTERVAL 5 DAY)); 
INSERT INTO LASTDAYS VALUES (DATE_SUB(CURRENT_TIMESTAMP,INTERVAL 6 DAY)); 

:このような表を作成する

最も簡単な方法は次のようなものになるだろう。ただし、これは7行にしか必要でないため、SELECTにも含めることができます。私は確信していませんが、BEGIN/ENDトランザクションブロックに囲まれていれば、一時テーブルはSELECT間にも保持されません。

関連する問題