我在Stackoverflow上搜索过这个答案,但我无法让任何已发布的解决方案适合我。
我有两张桌子:
builds:
build_id (INT)
status_id (INT)
created (INT)
和
statuses:
status_id (INT)
name (VARCHAR)
description (VARCHAR)
我想要一个查询,它将返回日期,构建状态以及该日期和状态的计数。如果特定状态的计数为0,我希望它返回0.例如:
+------------+-------+----------+
| date | count | name |
+------------+-------+----------+
| 2013-12-05 | 1 | Failed |
| 2013-12-05 | 2 | Stable |
| 2013-12-05 | 1 | Unstable |
| 2013-12-06 | 0 | Failed |
| 2013-12-06 | 1 | Stable |
| 2013-12-06 | 1 | Unstable |
+------------+-------+----------+
我在我的sql查询中尝试了各种左连接和ifnull组合。以下是不带0计数返回结果的查询:
SELECT FROM_UNIXTIME(created, '%Y-%m-%d') as date,
COUNT(statuses.status_id) as count, statuses.name
FROM builds
LEFT JOIN statuses on builds.status_id=statuses.status_id
GROUP BY date, name;
此查询显示:
+------------+-------+----------+
| date | count | name |
+------------+-------+----------+
| 2013-12-05 | 1 | Failed |
| 2013-12-05 | 2 | Stable |
| 2013-12-05 | 1 | Unstable |
| 2013-12-06 | 2 | Stable |
| 2013-12-06 | 1 | Unstable |
+------------+-------+----------+
提前谢谢。
值得一提的是,此处发布的解决方案有效:MySQL Group by - Get columns with zero count
除了他们需要where子句中的公司名称(在我的情况下的日期字段)...我想在一个查询中获得所有日期的列表。
答案 0 :(得分:0)
尝试:
SELECT FROM_UNIXTIME(created, '%Y-%m-%d') as date,
COUNT(builds.status_id) as count,
statuses.name
FROM builds
RIGHT JOIN statuses on builds.status_id=statuses.status_id
GROUP BY date, name;
或者也许:
SELECT FROM_UNIXTIME(created, '%Y-%m-%d') as date,
SUM(CASE WHEN builds.status_id IS NULL THEN 0 ELSE 1 END ) as count,
statuses.name
FROM builds
RIGHT JOIN statuses on builds.status_id=statuses.status_id
GROUP BY date, name;
COUNT(列)理论上应该只计算非空值,但谁知道......
答案 1 :(得分:0)
尝试右连接:
SELECT FROM_UNIXTIME(created, '%Y-%m-%d') as date,
COUNT(statuses.status_id) as count, statuses.name
FROM builds
RIGHT JOIN statuses on builds.status_id=statuses.status_id
GROUP BY date, name;
答案 2 :(得分:0)
我最后通过加入一个类似于这篇文章中建议的单独日历表来完成这项工作:SQL left joining multiple tables
以下是完整查询:
"SELECT
allRecords.date,
allRecords.Name,
( SELECT
COUNT(statuses.status_id)
FROM statuses, builds, calendar
WHERE builds.status_id = statuses.status_id
AND FROM_UNIXTIME(builds.created, '%Y-%m-%d') = calendar.date
AND calendar.date = allRecords.date
AND statuses.name = allRecords.Name
) as Count
FROM
( SELECT calendar.date,
statuses.status_id,
statuses.name
FROM
calendar,
statuses
ORDER BY
calendar.date,
statuses.name ) allRecords
LEFT JOIN builds
ON builds.status_id = allRecords.status_id
LEFT JOIN statuses
ON builds.status_id = statuses.status_id
WHERE allRecords.date BETWEEN
(SELECT MIN(FROM_UNIXTIME(builds.created, '%Y-%m-%d')) FROM builds)
AND
(SELECT MAX(FROM_UNIXTIME(builds.created, '%Y-%m-%d')) FROM builds)
GROUP BY
allRecords.date,
allRecords.Name
ORDER BY
allRecords.date,
CASE allRecords.Name
WHEN 'Stable' THEN 1
WHEN 'Unstable' THEN 2
WHEN 'Failed' THEN 3
ELSE 100 END";