将临时日期表与两个表组合并填写缺失值?

时间:2014-12-17 01:12:21

标签: mysql join

我有一张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。所以只缺少值。

1 个答案:

答案 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;