0

我有 2 个表,并尝试删除表 1 中的所有条目(每行多个单词),其中包含表 2 中的一个条目。表 2 中的这些词可以在表 1 的字符串中的某个位置。

它应该在“这里的大房子”或“大房子”中找到类似的东西:“房子”

它不应该找到这样的东西:“houses”中的“house”

我尝试使用这样的定位功能:

CREATE TABLE `test`
AS (
  SELECT
    `table1`.`term1`,
    `table2`.`term2`
  FROM `table1`,`table2`
  WHERE
    locate(concat(' ',`table2`.`term2`,' '), concat(' ',`table1`.`term1`,' '))
);

问题是:它找到了一些,但不是全部,我看不出背后的逻辑为什么它不能适用于所有事情。

4

1 回答 1

0

如果您要查找的单词周围有任何标点符号,则您的匹配将不起作用。

您可以将字段中的所有标点符号替换为空格

但是,我认为更清洁的解决方案是正则表达式

CREATE TABLE test
AS
SELECT table1.term1, table2.term2
FROM table1, table2
WHERE table1.term1 REGEXP CONCAT('(^|[^A-Za-z]])',table2.term2,'([^A-Za-z]|$)');

(^|[^A-Za-z])表示字段的开始或不是 AZ 或 az。
([^A-Za-z]|$)表示不是 AZ 或 az 或字段结束。

SQLFiddle

编辑:

虽然上述内容很漂亮,但它并不是特别有效。(140 ms在一个小测试中)

更高效:(80 ms在适当的数据上可能会更好)

SELECT term1, term2
FROM table1, table2
WHERE term1 LIKE CONCAT('%',term2,'%')
  AND term1 REGEXP CONCAT('(^|[^A-Za-z])',term2,'([^A-Za-z]|$)');

更有效的方式:8 ms)(出于某种奇怪的原因,MySQL 似乎不能很好地执行正则表达式)

SELECT COUNT(*)
FROM table1, table2
WHERE term1 LIKE CONCAT(term2,' %')
   OR term1 LIKE CONCAT(term2,',%')
   OR term1 LIKE CONCAT(term2,'.%')
   OR term1 LIKE CONCAT(term2,';%')
   OR term1 LIKE CONCAT('% ',term2,' %')
   OR term1 LIKE CONCAT('% ',term2,',%')
   OR term1 LIKE CONCAT('% ',term2,'.%')
   OR term1 LIKE CONCAT('% ',term2,';%')
   OR term1 LIKE CONCAT('% ',term2)

效率更高一点:( 4 ms)

SELECT COUNT(*)
FROM table1, table2
WHERE CONCAT(' ', REPLACE(REPLACE(REPLACE(term1, ',', ' '), '.', ' '), ';', ' '), ' ')
        LIKE CONCAT('% ',term2,' %')

您可能希望在上面包含更多字符。

SQLFiddle

请注意,以上大部分内容取决于数据,有些可能在某些情况下效率更高,而在其他情况下则更糟(但正则表达式可能会落后)。

更有效率?

全文索引 + 搜索

于 2013-03-04T11:08:08.717 回答