我有一张rates
表,其中包含每天每晚的行数。我有一个ratecodes
表,其中包含映射到rates
的不同速率代码。
我的目标是在X段时间内找到任何缺失的rates
。对于这个例子,我们使用1个月。
期望的结果:64行,其中2行用第一速率代码填充信息。第二个费率代码在rates
中绝对没有行,但我需要证明它实际上缺少日期。 ( 64因为从现在起1个月后返回32天x 2费率代码)
有问题的两个表:
CREATE TABLE `ratecode` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`ratecode` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
INSERT INTO `ratecode` VALUES ('1', 'BLAH');
INSERT INTO `ratecode` VALUES ('2', 'NAH');
CREATE TABLE `rates` (
`thedate` date DEFAULT NULL,
`rate` double DEFAULT NULL,
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`ratecode` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
INSERT INTO `rates` VALUES ('2014-12-27', '999', '1', '1');
INSERT INTO `rates` VALUES ('2014-12-26', '99', '2', '1');
因此使用此查询,分为两部分。第1部分是从今天到1个月的临时日期表:
CREATE TEMPORARY TABLE IF NOT EXISTS `myDates` AS (
SELECT
CAST((SYSDATE()+INTERVAL (H+T+U) DAY) AS date) d
FROM ( SELECT 0 H
UNION ALL SELECT 100 UNION ALL SELECT 200 UNION ALL SELECT 300
) H CROSS JOIN ( SELECT 0 T
UNION ALL SELECT 10 UNION ALL SELECT 20 UNION ALL SELECT 30
UNION ALL SELECT 40 UNION ALL SELECT 50 UNION ALL SELECT 60
UNION ALL SELECT 70 UNION ALL SELECT 80 UNION ALL SELECT 90
) T CROSS JOIN ( SELECT 0 U
UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3
UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6
UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9
) U
WHERE
(SYSDATE()+INTERVAL (H+T+U) DAY) <= (SYSDATE()+INTERVAL 1 MONTH)
ORDER BY d ASC
);
第2部分是实际选择:
SELECT
*
FROM
rates
RIGHT JOIN myDates ON ( myDates.d = rates.thedate )
LEFT OUTER JOIN ratecode ON ( rates.ratecode = ratecode.id )
这只返回32行,因为在rates
中,ratecode
中的第一个条目有2条记录。我没有收回其他价目代码的32个缺失行。如何调整以保留此信息?
我收到64行后,我还需要过滤哪些是“空白”或尚未输入rates
。所以只缺少值。
答案 0 :(得分:1)
如果我理解正确,您希望使用cross join
生成所有行,然后使用left join
生成数据并过滤掉所有匹配项:
select rc.ratecode, d.d as missingdate
from ratecode rc cross join
mydates d left join
rates r
on rc.id = r.ratecode and d.d = r.thedate
where r.id is null;