给定一个表格,其中包含一段时间内每一天的日期
CREATE TABLE `tbl_calendar` (
`date` date NOT NULL,
PRIMARY KEY (`date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
INSERT INTO `tbl_calendar` (`date`)
VALUES
('2016-12-10'),
('2016-12-09'),
('2016-12-08'),
('2016-12-07'),
('2016-12-06'),
('2016-12-05'),
('2016-12-04'),
('2016-12-03'),
('2016-12-02'),
('2016-12-01')
;
以及一个包含不同类型的值的表,在没有填充它们的随机日期缺少值。
CREATE TABLE `tbl_values` (
`value_id` int(11) NOT NULL AUTO_INCREMENT,
`type_id` int(11) NOT NULL DEFAULT '0',
`date` date DEFAULT NULL,
`value` double(15,2) DEFAULT '0.00',
PRIMARY KEY (`value_id`),
KEY `type_id_date` (`type_id`,`date`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
INSERT INTO `tbl_values` (`type_id`, `date`, `value`)
VALUES
(100, '2016-12-02', 1),
(100, '2016-12-04', 2),
(100, '2016-12-06', 3),
(100, '2016-12-08', 4),
(100, '2016-12-10', 5)
;
如何使用该类型的最新记录在 SELECT 中返回缺失天数的值?这是我到目前为止所拥有的。
SELECT
v1.type,
c.date,
v1.value
FROM
tbl_calendar c
LEFT JOIN tbl_values v1 ON (
v1.type_id = 100
AND v1.date <= c.date
)
LEFT JOIN tbl_values v2 ON (
v2.type_id = 100
AND v2.date < c.date
AND v2.date > o1.date
)
WHERE
v1.date = c.date
OR v2.date IS NULL
此查询的问题在于,当该日期有值时,它会返回以前的最新记录值,以及具有正确值的记录。
预期产出
a_vlad 的答案在结果上是正确的,但性能不佳,这是预期的。
SELECT
t1.date,
(SELECT v1.type_id FROM tbl_values v1 where v1.date <= t1.date ORDER BY v1.date desc limit 1) as `type`,
(SELECT v1.`value` FROM tbl_values v1 where v1.date <= t1.date ORDER BY v1.date desc limit 1) as `value`
FROM tbl_calendar t1
HAVING `type` IS NOT NULL
我使用的最终解决方案是使用 a_vlad 查询来创建汇总表。然而,事实证明它并没有提高系统的性能(因为以前缺失的值是在 PHP 循环中填充的,结果速度一样快)