MySql で、幾つかあるテーブルの件数を時々(毎日では無いという意味)集計して、前回の集計からどれくらい増えたかを報告するような SQL を試しました。
取り合えず 2 テーブル(atable/btable)で、ttable に集計を入れて select で表示させます。
CREATE TABLE ttable (
date DATE NOT NULL,
asum INT NOT NULL,
bsum INT NOT NULL,
UNIQUE KEY `date`(`date`));
前回値が必要なので過去のテキトウな日付で 1 件
INSERT INTO ttable(date, asum, bsum) VALUES ('2000-01-01',0,0);
で、集計する日に
INSERT INTO ttable(date, asum, bsum)
SELECT CURDATE(), SUM(a) AS asum, SUM(b) AS bsum
FROM (
SELECT COUNT(*) AS a, '0' AS b FROM atable
UNION ALL
SELECT '0' AS a, COUNT(*) AS b FROM btable) AS t
ON DUPLICATE KEY UPDATE
asum=VALUES(asum), bsum=VALUES(bsum);
とかすると
+------------+------+------+
| date | asum | bsum |
+------------+------+------+
| 2000-01-01 | 0 | 0 |
| 2025-02-25 | 3 | 2 |
+------------+------+------+
のように行が増えて
SELECT CONCAT('A合計 ',FORMAT(a2,0),'(+',FORMAT(a2-a1,0),')\n',
'B合計 ',FORMAT(b2,0),'(+',FORMAT(b2-b1,0),')\n',
'総合計 ',FORMAT(a2+b2,0),'(+',FORMAT(a2-a1+b2-b1,0),')') AS t
FROM
(SELECT asum AS a2, bsum AS b2 FROM ttable ORDER BY date DESC LIMIT 1) AS c,
(SELECT asum AS a1, bsum AS b1 FROM ttable ORDER BY date DESC LIMIT 1,1) AS p;
で
+---------------------------------------------+
| t |
+---------------------------------------------+
| A合計 3(+3)
B合計 2(+2)
総合計 5(+5) |
+---------------------------------------------+
となるのですね。
コピペで報告。
SELECT の FROM を LEFT OUTER JOIN に出来れば ttable の初期レコードは要らなくなるかもしれませんが、今の所出来るか分かりません。
UPSERT で使っている VALUES は無くなるそうなので別の書き方にしないといけないという記事は見ましたが、どうするんだったか忘れました。
UPSERT の VALUES() を行エイリアスにすると同時に、UNION ALL を列サブクエリにしてみたら、このほうがスッキリした感じです。
INSERT INTO ttable(date, asum, bsum)
SELECT * FROM (
SELECT CURDATE() AS date,
(SELECT COUNT(*) FROM atable) AS asum,
(SELECT COUNT(*) FROM btable) AS bsum
) AS new
ON DUPLICATE KEY UPDATE
asum=new.asum, bsum=new.bsum;