我有这样的查询
SELECT count(Distinct name) as total, DATE_FORMAT(date_added, '%M %d, %Y') AS date_added
FROM `submitted_changes`
WHERE date_added >= NOW() - INTERVAL 1 WEEK
GROUP BY DATE(date_added)
它工作得很好,并返回具有格式良好的日期和总数的行。基本上,这表示每天提交的数量。
我遇到的问题是处理提交0天的日子。我现在不想跳过这些日子,而是显示日期,total
为0。有没有办法确保当我执行上面的查询(仅包括过去一周[7天]的日期)时,我总会得到7行?
答案 0 :(得分:1)
要执行此操作,您需要每个日期都存在记录。由于您的submitted_changes
表格不是这种情况 - 我建议您创建一个日期表(如果您还没有)。
注意 - 对于最短的版本,请检查底部的最后一次编辑:
以下是临时表的示例。首先运行:
CREATE TEMPORARY TABLE IF NOT EXISTS dates AS
SELECT DATE(curdate()-num) as date_col
FROM
(
SELECT 0 as num
UNION
SELECT 1
UNION
SELECT 2
UNION
SELECT 3
UNION
SELECT 4
UNION
SELECT 5
UNION
SELECT 6) sub
这将创建一个包含7个相关日期的表。
现在left join
包含您的数据:
SELECT
count(Distinct name) as total,
DATE_FORMAT(date_col, '%M %d, %Y') AS date_added
FROM dates LEFT JOIN submitted_changes
on (dates.date_col = DATE(submitted_changes.date_added))
GROUP BY date_col
您也可以将其作为一次性查询(没有create
语句)运行:
SELECT
count(Distinct name) as total,
DATE_FORMAT(date_col, '%M %d, %Y') AS date_added
FROM
(SELECT DATE(curdate()-num) as date_col
FROM
(
SELECT 0 as num
UNION
SELECT 1
UNION
SELECT 2
UNION
SELECT 3
UNION
SELECT 4
UNION
SELECT 5
UNION
SELECT 6) sub) dates
LEFT JOIN submitted_changes
on (dates.date_col = DATE(submitted_changes.date_added))
GROUP BY date_col
另一种方法是永久dim_date
。以下是静态表的示例代码(包含更多额外字段):
CREATE TABLE dim_date (
id int(11) NOT NULL AUTO_INCREMENT,
date date,
day int(11),
month int(11),
year int(11),
day_name varchar(45),
PRIMARY KEY (id),
INDEX date_index (date)
)
然后填充它:
SET @currdate := "2015-01-01";
SET @enddate := "2025-01-01";
delimiter $$
DROP PROCEDURE IF EXISTS BuildDate$$
CREATE PROCEDURE BuildDate()
BEGIN
WHILE @currdate < @enddate DO
INSERT INTO dim_date (date, day, month, year, day_name)
VALUES (
@currdate, DAY(@currdate), MONTH(@currdate),
YEAR(@currdate), DAYNAME(@currdate)
);
SET @currdate := DATE_ADD(@currdate, INTERVAL 1 DAY);
END WHILE;
END$$
CALL BuildDate();
然后,您最终可以使用left join
:
SELECT
count(Distinct name) as total,
DATE_FORMAT(date, '%M %d, %Y') AS date_added
FROM dim_date LEFT JOIN submitted_changes
on (dim_date.date = DATE(submitted_changes.date_added))
WHERE date >= NOW() - INTERVAL 1 WEEK
GROUP BY date
即使submitted_changes
中没有记录,也会为每个日期返回一行。
修改:受this post启发的另一个一次性超短版本:
SELECT
count(Distinct name) as total,
DATE_FORMAT(date, '%M %d, %Y') AS date_added
(SELECT date(curdate()-id%7) as date
FROM submitted_changes
GROUP BY num) dates LEFT JOIN submitted_changes
on (date.dates = DATE(submitted_changes.date_added))
GROUP BY date