我的StoredProcedure只给出了结果中最大行数等于表格的条目数量。
所以call SP_Dashboard_getTransactionsPerDay("2018-03-19", "2018-04-25")
会给我:
date | total
-----------------
2018-03-19| 0
2018-03-19| 0
如果event
表中有2个条目,而不是完整的38个请求日期。如果event
中有6个条目,则同一调用会给我6行;如果event
中至少有38个或更多条目,则会给我38个行。
即使event
表格中没有条目,有没有办法获得所有请求日期的结果?
我的SP看起来如下:
CREATE PROCEDURE `SP_Dashboard_getTransactionsPerDay`(STARTDATE DATE,ENDDATE DATE)
BEGIN
set @i := -1;
SELECT
DATE(ADDDATE(STARTDATE, INTERVAL @i:=@i+1 DAY)) AS date,
IFNULL(
(
SELECT
COUNT(*) FROM event AS m2
WHERE
DATE(m2.created_at) = DATE(ADDDATE(STARTDATE, INTERVAL @i DAY))
AND `m2`.`status` = 'ok'
),
0) AS total
FROM
event AS m1;
HAVING
@i < DATEDIFF(ENDDATE, STARTDATE);
END
表DDL:
CREATE TABLE `event` (
`id` int(15) NOT NULL AUTO_INCREMENT,
`status` enum('new','ok','error') COLLATE utf8_bin NOT NULL DEFAULT 'new',
`created_at` datetime NOT NULL,
`updated_at` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
答案 0 :(得分:0)
添加日历/日期表通过将以下内容添加到我的数据库中解决了这个问题:
新表:
-- -----------------------------------------------------
-- Table `dates`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `dates`;
CREATE TABLE `dates` (
`date` DATE NOT NULL,
PRIMARY KEY (`date`)
)
ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8 COLLATE = utf8_bin;
自动填充新表的存储过程:
-- -----------------------------------------------------
-- StoredProcedure `SP_filldates`
-- -----------------------------------------------------
DROP PROCEDURE IF EXISTS SP_filldates;
DELIMITER $$
CREATE PROCEDURE SP_filldates(STARTDATE DATE, ENDDATE DATE)
BEGIN
WHILE STARTDATE <= ENDDATE DO
INSERT INTO dates (date) VALUES (STARTDATE);
SET STARTDATE = date_add(STARTDATE, INTERVAL 1 DAY);
END WHILE;
END;
$$
DELIMITER ;
CALL SP_filldates('2018-01-01', '2018-12-31');
并修改了我最初发布的存储过程:
-- -----------------------------------------------------
-- StoredProcedure `SP_Dashboard_getTransactionsPerDay`
-- -----------------------------------------------------
DROP PROCEDURE
IF EXISTS SP_Dashboard_getTransactionsPerDay;
DELIMITER $$
CREATE PROCEDURE SP_Dashboard_getTransactionsPerDay(
STARTDATE DATE,
ENDDATE DATE
)
BEGIN
SET @i := -1;
SELECT
DATE(ADDDATE(STARTDATE, INTERVAL @i := @i + 1 DAY)) AS date,
IFNULL(
(
SELECT COUNT(*)
FROM event AS m2
WHERE
DATE(m2.created_at) = DATE(ADDDATE(STARTDATE, INTERVAL @i DAY))
AND `m2`.`status` = 'ok'
),
0
) AS total
FROM
dates AS m1
HAVING
@i < DATEDIFF(ENDDATE, STARTDATE);
END$$
DELIMITER ;
此修复程序适用于最多365行的所有请求,因为在这种情况下,日期表只包含365个条目。如果需要更多结果,则日期表必须包含更多日期。