最初の行は、あなたがコードをいじるされていると、古いバージョンを削除したいときに便利です
DROP PROCEDURE IF EXISTS SumCountAllDays;
DELIMITER //
CREATE PROCEDURE SumCountAllDays(startDate DATE,
endDate DATE)
BEGIN
DECLARE daysCount INT;
DECLARE daysIndex INT DEFAULT 0;
SELECT DATEDIFF(endDate,
startDate)
INTO daysCount;
SET @selectStatementString := CONCAT("SELECT allDays.intervalDate AS `Date`,",
" COALESCE(SUM(`count`), 0) AS totalCount ",
"FROM (SELECT '",
startDate,
"' AS intervalDate");
daysLister : LOOP
SET daysIndex = daysIndex + 1;
IF daysIndex <= daysCount THEN
SET @selectStatementString := CONCAT(@selectStatementString,
" UNION SELECT '",
DATE_ADD(startDate,
INTERVAL daysIndex DAY),
"'");
ITERATE daysLister;
END IF;
LEAVE daysLister;
END LOOP daysLister;
SET @selectStatementString := CONCAT(@selectStatementString,
") AS allDays ",
"LEFT JOIN tableName ON allDays.intervalDate = DATE(`datetime`) ",
"GROUP BY allDays.intervalDate;");
PREPARE selectStatement FROM @selectStatementString;
EXECUTE selectStatement;
DEALLOCATE PREPARE selectStatement;
END //
DELIMITER ;
...次のことを試してみてください。
コードの残りの部分は問題に呼ばれ、期間の開始日と終了日を経過したときには、daysCount
に値を格納し、日間とstartDate
とendDate
などの数を計算するDATEDIFF()
を使用して開始することプロシージャを作成します。
この手順では、@selectStatementString
が最終的な声明の最初の部分に初期化されます。この最初の部分は、startDate
とendDate
を含む各日付を選択するために使用される一連のSELECT
ステートメントの最初の部分で終了します。このSELECT
の初期値はstartDate
であり、これらすべての日付の和集合によって形成されるフィールドの名前はintervalDate
です。
ループには、ループのインデックスdaysIndex
に基づいて計算された日付ごとにSELECT
が追加されます。
UNION
演算子は、生成された日付ごとに垂直結合を実行するために使用されます。
LOOP
が終了した後、残りのステートメントがこれまでのステートメントに追加されます。 startDate
とendDate
が2012-02-13
と2012-02-15
だったなら、私たちは今、次の文を持っているでしょう...
SELECT allDays.intervalDate AS `Date`,
COUNT(`count`) AS totalCount
FROM (SELECT '2012-02-13' AS intervalDate
UNION
SELECT '2012-02-14'
UNION
SELECT '2012-02-15') AS allDays
LEFT JOIN tableName ON allDays.intervalDate = DATE(`datetime`)
GROUP BY allDays.intervalDate;
私は、テスト・データベースに対して、私の文は次のスクリプトを使用して作成したテスト...
CREATE TABLE tableName
(
`datetime` DATETIME,
`count` INT
);
INSERT INTO tableName (`datetime`,
`count`)
VALUES ('2012-12-27 09:22:15', 5),
('2012-12-27 18:20:15', 4),
('2012-12-27 23:19:15', 3),
('2012-12-26 13:45:15', 8),
('2012-12-26 04:56:15', 7),
('2012-12-25 01:50:15', 2),
('2012-12-25 12:02:15', 1);
私はあなたが何か質問やコメントがあれば、それに応じてコメントを投稿すること自由に感じなさい
CALL SumCountAllDays('2012-12-01',
'2012-12-31');
...次のステートメントを使用してプロシージャを呼び出しました。
あなたはそこにないものを選択することはできません。おそらく、生成されたリストへの結合を含むいくつかのハックな解決策がありますか?しかしおそらくそうではありません。私はあなたのデータベースにすべての日のリストが必要だと言います。 – Pharaoh
カレンダーテーブルを使用します。あなたはこれのためにGoogleにすることができ、多くのものを見つけるでしょう。 –
だから、テーブルの最小日付から最大日付までの合計を必要とします。そうですか? – Avi