使用MySQL" NOT IN"但允许子串

时间:2015-07-17 23:25:40

标签: mysql

我正在尝试查询不在另一组行中的行。但是,另一组行可能包含包含第一个表中的字符串的字符串。

我迷惑自己试图解释所以我将使用以下示例表:

mysql> DESCRIBE tablea;
+------------+----------+------+-----+---------+-------+
| Field      | Type     | Null | Key | Default | Extra |
+------------+----------+------+-----+---------+-------+
| name       | char(40) | NO   | PRI |         |       | 
+------------+----------+------+-----+---------+-------+

mysql> DESCRIBE tableb;
+------------+----------+------+-----+---------+-------+
| Field      | Type     | Null | Key | Default | Extra |
+------------+----------+------+-----+---------+-------+
| nametag    | char(40) | NO   | PRI |         |       | 
+------------+----------+------+-----+---------+-------+

mysql> SELECT name FROM tablea;
+------------+
| name       |
+------------+
| cat        |
| dog        |
| cow        |
+------------+

mysql> SELECT nametag FROM tableb;
+------------+
| nametag    |
+------------+
| wolf       |
| dog        |
| browncow   |
+------------+

我正在尝试找到一种类似于NOT IN操作的方法,但是因为 cow 是"在" browncow ,我也想排除这个值。

mysql> SELECT name FROM tablea WHERE name NOT IN ( SELECT nametag FROM tableb );
+------------+
| name       |
+------------+
| cat        |
| cow        |
+------------+
# I am looking for something that would only return "cat" for this example.

是否有任何操作我可以使用其他修饰符搜索不包含在另一组中的行?

2 个答案:

答案 0 :(得分:3)

您可以使用反连接模式,使用LIKE谓词进行匹配。 (反连接是一个外连接,用于从一个表返回所有行,以及来自另一个表的匹配,然后是排除的行的谓词一场比赛

  SELECT a.name
    FROM tablea a
    JOIN tableb b
      ON b.nametag LIKE CONCAT('%',a.name,'%')
   WHERE b.nametag IS NULL

a中来自b的匹配行的所有行...来自b的行将具有非NULL值。或者,换句话说。 ..来自a的{​​{1}}中没有匹配行的行将为b中的列提供NULL值。)

如果b中有a行,name='cow'中有b行,那么这些行就会匹配。

如果字符nametag='browncow'没有出现在a的任何值中,则只会返回name='cat''cat'的行。

注意:百分号和下划线字符是b.nametag谓词中的通配符。如果你想对这些角色进行匹配,你需要逃避"逃避"那些有反斜杠的人。使用LIKE匹配存在类似的问题,但更多可能的恶作剧角色。

还有其他查询模式会返回相同的结果。

例如:

REGEXP

就个人而言,我更喜欢反连接模式。

答案 1 :(得分:1)

使用“NOT EXISTS”和INSTR

select *
  from tablea a
 where not exists(select 1 from tableb b where INSTR(a.name, b.nametag) > 0)
;

要排除空字符串:

select *
  from tablea a
 where not exists(select 1 from tableb b where INSTR(a.name, b.nametag) > 0)
   and length(a.name) > 0
;