多表记录数统计问题:按日期查询city等表记录数报错
按日期统计多表记录数的SQL解决方案
需求
对数据库中的city、account、alarm三张表,按日期分别统计每张表的每日记录数,预期输出格式如下:
| table_name | date | count |
|---|---|---|
| Alarm | 26-04-2024 | 5346 |
| alarm | 25-04-2024 | 6766 |
| city | 26-04-2024 | 5346 |
| city | 25-04-2024 | 6766 |
| account | 26-04-2024 | 5346 |
| account | 25-04-2024 | 6766 |
错误查询与问题
错误语句
select (select count(*) from "table_name" group by to_date(ingest_time)) as city, (select count(*) from "table_name" group by to_date(ingest_time)) as alarm from dual;
报错信息
Single-row subquery returns more than one row.
(中文翻译:单行子查询返回了多行结果)
错误原因
- 子查询中使用
GROUP BY to_date(ingest_time)会返回多条日期对应的统计结果(多行),但主查询将子查询作为列值,要求子查询必须返回单行,因此触发报错。 - 语句中表名写死为
"table_name",未指定实际要统计的city、alarm等表,逻辑错误。
正确解决方案
通过UNION ALL分别统计每张表的日期记录数并合并结果:
SELECT 'city' AS table_name, TO_CHAR(TO_DATE(ingest_time), 'DD-MM-YYYY') AS date, COUNT(*) AS count FROM city GROUP BY TO_DATE(ingest_time) UNION ALL SELECT 'account' AS table_name, TO_CHAR(TO_DATE(ingest_time), 'DD-MM-YYYY') AS date, COUNT(*) AS count FROM account GROUP BY TO_DATE(ingest_time) UNION ALL SELECT 'alarm' AS table_name, TO_CHAR(TO_DATE(ingest_time), 'DD-MM-YYYY') AS date, COUNT(*) AS count FROM alarm GROUP BY TO_DATE(ingest_time) ORDER BY table_name, date DESC;
说明
- 每个
SELECT块单独统计一张表的每日记录数,并显式指定表名 - 使用
TO_CHAR将日期格式化为DD-MM-YYYY格式,匹配预期输出 UNION ALL用于合并三张表的统计结果,保留所有行(无需去重)- 末尾
ORDER BY可按需对结果按表名和日期排序,提升可读性
内容的提问来源于stack exchange,提问作者Soumith Bharadwaj
相关产品推荐
相关产品推荐

