"反向加入"需要,使用mysql

时间:2018-03-26 22:10:39

标签: mysql

我需要做一些我描述为"反向加入" - 也就是说,我需要在表A中创建一个不在表B中的行列表,其中A.FNAME像B.FNAME和A.LNAME,如B.LNAME。关键是提取在先前邮件中被忽略的邮件列表条目。不幸的是,两个表之间的主键不一致。由于缺乏经验的操作员,表B在最初创建时无法从表A中复制它们。

没有为"反向加入"返回的搜索响应似乎解决了这种情况;我是否想要证明是消极的"这里?我以为我可以创建一个完整邮件列表的临时表,然后从它中删除每个在较短列表中有匹配的FNAME和LNAME的行,但我似乎无法在不破坏较短列表的情况下执行此操作。过程

3 个答案:

答案 0 :(得分:0)

不需要加入:

SELECT * 
FROM tableA
WHERE (fname, lname) NOT IN (SELECT fname, lname FROM tableB)

但可以用一个完成:

SELECT a.*
FROM tableA AS s
LEFT JOIN tableB as b ON a.fname = b.fname AND a.lname = b.lname
WHERE b.somefield_that_cannot_be_null IS NULL

第二个版本通常是我的第一直觉(加入时我的索引运气更好)但由于涉及的字段不太可能被编入索引,而且字符串比较无论如何相对昂贵,我认为第一个版本的意图是更加清晰。

注意:LIKE是不必要的,除非您期望字段值中的通配符(%)...在这种情况下,连接版本是这两者中唯一的选项。

答案 1 :(得分:0)

您也可以使用OnOpenedListener条款来实现这一点,即。

NOT EXISTS

如果您需要,此方法还允许您使用SELECT * FROM tableA AS A WHERE NOT EXISTS (SELECT * FROM tableB AS B WHERE A.FNAME LIKE B.FNAME AND A.LNAME LIKE B.LNAME) 进行比较,但我怀疑您确实想要=。

答案 2 :(得分:0)

正如Uueerdo所示,使用反连接模式。

SELECT a.*
  FROM `table A` a

LEFT
 JOIN `table B` b
   ON b.fname = a.fname 
  AND b.lname = a.lname

WHERE b.fname IS NULL 

让我们稍微打破一下。

它是一个外部联接,用于返回A中的所有行以及来自B的匹配行,其中包含WHERE子句中的条件。< / p>

我们在table B找到匹配项的任何行,我们保证b.fnameb.lname都是非空的。 (如果其中一列为NULL,则连接谓词中的相等条件不会被满足,而B中的行也不会匹配。

来自A的{​​{1}}中未找到匹配项的任何行都将为B中的所有列提供NULL值。如果我们排除B中保证为非NULL的任何列中具有非NULL值的所有行,那么我们剩下的是来自B的行没有的行A中的匹配。

反连接是我们的SQL工具带中非常有用的模式。

使用B模式可以获得等效结果。 (见尼克的答案,以示例。)

奇怪的是,在MySQL 5.6中,有适当的索引可用于&#34; 反连接&#34;查询模式,EXPLAIN输出实际显示&#34; 不存在&#34;。

NOT EXISTS

对于等效的&#34; 不存在&#34;查询时,EXPLAIN输出略有不同,显示了一个从属子查询。

-- explain antijoin
id  select_type        table type key  rows    Extra        
--  ------------------ ----- ---- ---- ------  ------------------------------------
 1  SIMPLE             a     ALL       210339 
 1  SIMPLE             b     ref  FK_a      1  Using where; Not exists; Using index

就个人而言,我选择反加入,因为我倾向于看到最好的表现。 (-- explain "not exists" equivalent id select_type table type key rows Extra -- ------------------ ----- ---- ---- ------ ------------------------------------ 1 PRIMARY a ALL 210339 Using where 2 DEPENDENT SUBQUERY b ref FK_a 1 Using index 模式可能会提供更好的效果,NOT EXISTS我们不太可能看到更好的效果。