我有两个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个差异,是否有可用于识别它们的脚本?
答案 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)