我有2个表,并尝试删除表1中的所有条目(每行多个单词),其中包含表2中的一个条目。表2中的这些单词可以位于表1的字符串中。
它应该找到这样的东西:'房子'在'大房子里'或'大房子'
它不应该找到这样的东西:'house'中的'house'
我尝试使用这样的locate函数:
CREATE TABLE `test`
AS (
SELECT
`table1`.`term1`,
`table2`.`term2`
FROM `table1`,`table2`
WHERE
locate(concat(' ',`table2`.`term2`,' '), concat(' ',`table1`.`term1`,' '))
);
问题是:它找到了一些,但不是全部,我无法看到其背后的逻辑,为什么它不适用于所有事情。
答案 0 :(得分: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])
表示字段的起点或不是A-Z或a-z
([^A-Za-z]|$)
表示不是A-Z或a-z或字段结尾。
修改强>
虽然上述情况非常好,但并不是特别有效。 (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,' %')
您可能希望在上面添加更多字符。
请注意,上述大部分内容取决于数据,有些可能在某些情况下更有效,而在其他情况下则更差(但正则表达式可能会落后)。
效率更高?