MySQL - 找到孤儿行

时间:2016-04-11 14:12:22

标签: mysql

我有两个MySQL表(testa,resa),如下面的小样本:

       CREATE TABLE RESA (
       `tdate` date,
       `reg` varchar(4), 
       `num` int(2), 
       `P1`  int(2), 
       `P2`  int(2),    
       `P3`  int(2), 
       `P4`  int(2)   
       ); 

       CREATE TABLE TESTA (
       `tdate` date,
       `reg` varchar(4), 
       `numa` int(2), 
       `numb` int(2),
       `name` varchar(10),
       `reso` varchar(2)
       );

       INSERT INTO RESA VALUES 
       ("2015-12-06", 'NERA', 2, 1,2,3,4),
       ("2015-12-06", 'WAS', 5, 5,6,7,9),
       ("2015-12-08", 'NERA', 1, 3,5,6,8);

      INSERT INTO TESTA VALUES 
      ("2015-12-06", 'NERA', 2,1, 'Qalyub',""),
      ("2015-12-06", 'NERA', 2,2, 'Kunjin',""),
      ("2015-12-06", 'NERA', 2,3, 'Carrizal',""),
      ("2015-12-07", 'NERA', 2,4, 'Amur',""),
      ("2015-12-06", 'NERA', 2,6, 'Heni',""),
      ("2015-12-06", 'NERA', 2,7, 'El Moro',""),
      ("2015-12-07", 'NERA', 2,10, 'Fifth-C',""),
      ("2015-12-06", 'WAS', 5,2, 'Bora',""),
      ("2015-12-06", 'WAS', 5,3, 'Imjin',""),
      ("2015-12-06", 'WAS', 5,5, 'RR',""),
      ("2015-12-07", 'WAS', 5,6, 'Qalyub',""),
      ("2015-12-06", 'WAS', 5,7, 'RR',""),
      ("2015-12-07", 'WAS', 5,9, 'Qalyub',""),
      ("2015-12-07", 'NERA', 1,2, 'Kunjin',""),
      ("2015-12-07", 'NERA', 1,3, 'Carrizal',""),
      ("2015-12-07", 'NERA', 1,5, 'Amur',""),
      ("2015-12-07", 'NERA', 1,6, 'Bora',""),
      ("2015-12-07", 'NERA', 1,7, 'Imjin',""),
      ("2015-12-07", 'NERA', 1,8, 'Magboy',"") ;  

实际表包含数千行和其他列。

对于每个RESA行,存在可变数量的关联TESTA行,其中每个表的前3个字段(date,reg,num / date,reg,numa)建立关系。两个表中的行都不同,即没有重复。

每个实验结果(RESA)行至少有2个测试(TESTA)行。

当每个表的前3个字段匹配时,只有一个TESTA行中的RESA.p1和TESTA.numb匹配,因此以下将返回两个表中将用于的所有相关行将更新应用于TESTA中的其他cols:

SELECT * FROM TESTA as T
  NATURAL JOIN RESA AS R
  WHERE T.numb = R.p1;

因此,要更新的TESTA行数应与表RESA中的行数相匹配,即以下计数将相同:

mysql>SELECT count(*) FROM TESTA as T
           NATURAL JOIN RESA AS R
           WHERE T.numb = R.p1;



mysql>SELECT COUNT(*) FROM RESA;  

在示例数据中它们不一样,这是我试图识别的问题。在小样本中,罪魁祸首很容易找到:最后一行的RESA.tdate :(" 2015-12-08",' NERA',1,3,5,6, 8);是不正确的,应该是" 2015-12-07"匹配TESTA中的相关数据。

我的问题是如何用更大的数据库识别RESA中的孤儿,即那些在TESTA中没有相关数据的行?

以上的反面:

SELECT count(*) FROM TESTA as T
           NATURAL JOIN RESA AS R
           WHERE T.numb != R.p1;

不起作用,因为相关字段没有NATURAL JOIN,因为RESA具有唯一的(即在TESTA中不存在且不正确)tdate值。

我的实际数据库有数千行,有2个差异,是否有可用于识别它们的脚本?

1 个答案:

答案 0 :(得分:6)

类似于LEFT JOIN

SELECT t.* FROM RESA t
LEFT OUTER JOIN TESTA s
 ON(t.tdate = s.tdate AND t.reg = s.reg and t.num = s.numa)
WHERE s.tdate is null

NOT EXISTS()

SELECT t.* FROM RESA t
WHERE NOT EXISTS(SELECT 1 FROM TESTA s
                 WHERE t.tdate = s.tdate
                   AND t.reg = s.reg 
                   AND t.num = s.numa)