我希望有一个SQL公式,以任意顺序匹配查询中的所有单词,而不使用多个'AND like'语句。
例如,查询'cat dog'应匹配以下语句: '猫与狗在公园里' '狗和猫正在玩'
我在Regex中找到了一个解决方案:
WHERE query REGEXP concat('\'(?=.*',replace('cat dog',' ',')(?=.*'),')\'')
注意:REGEXP之后的部分转换为'(?=。* cat)(?=。* dog)'
但是,我从regexp'得到错误'repeatition-operator operand invalid。
你能帮忙找到另一种方法让它发挥作用吗?
查询是一个免费字段(搜索框),因此可以匹配许多字词。这就是我不使用的原因:
WHERE query like '%cat%' AND query like '%dog%'
提前多多感谢!
凯文
答案 0 :(得分:0)
我认为这是你想要的。
Hitesh> select * from test;
+-------------------------+
| name |
+-------------------------+
| i am the boss |
| You will get soon |
| Happy birthday bro |
| the beautiful girl |
| oyee its sunday |
| cat and dog in a park |
| dog and cat are playing |
| cat |
| dog |
+-------------------------+
9 rows in set (0.00 sec)
Hitesh> set @a='cat';
Query OK, 0 rows affected (0.00 sec)
Hitesh> set @b='dog';
Query OK, 0 rows affected (0.00 sec)
Hitesh> set @var=concat(concat('((^(',@a,') .*)|(.* (',@a,') .*))'),'.*',concat('(.* (',@b,') .*)|(','.* (',@b,')$)'));
Query OK, 0 rows affected (0.00 sec)
Hitesh> set @var2=concat(concat('((^(',@b,') .*)|(.* (',@b,') .*))'),'.*',concat('((.* (',@a,') .*)|(','.* (',@a,')$))'));
Query OK, 0 rows affected (0.00 sec)
Hitesh> select @a, @b, @var, @var2;
+------+------+--------------------------------------------------------+----------------------------------------------------------+
| @a | @b | @var | @var2 |
+------+------+--------------------------------------------------------+----------------------------------------------------------+
| cat | dog | ((^(cat) .*)|(.* (cat) .*)).*(.* (dog) .*)|(.* (dog)$) | ((^(dog) .*)|(.* (dog) .*)).*((.* (cat) .*)|(.* (cat)$)) |
+------+------+--------------------------------------------------------+----------------------------------------------------------+
1 row in set (0.00 sec)
Hitesh> select * from test where (name REGEXP @var) or (name REGEXP @var2);
+-------------------------+
| name |
+-------------------------+
| cat and dog in a park |
| dog and cat are playing |
+-------------------------+
2 rows in set (0.00 sec)
答案 1 :(得分:0)
嗯,包括简单的复数(通过添加一个's'而形成)可以通过以下方式满足:
SELECT
query
FROM T
WHERE
CONCAT(',', REPLACE(query, ' ', ','), ',')
REGEXP CONCAT(',', REPLACE('cat dog', ' ', 's?,|,'), 's?,')
;
查看实际操作:SQL Fiddle 但是,这只是检查是否找到至少一个搜索词。
如果每个搜索字词(仍包括简单复数)至少需要找到一次,那么可以尝试一下
SELECT
query
FROM T
WHERE
CASE (LENGTH(@search) - LENGTH(REPLACE(@search, ' ', '')))
WHEN 0
THEN
(CONCAT(',', REPLACE(query, ' ', ','), ',') REGEXP CONCAT(',', @search, 's?,'))
WHEN 1
THEN
(CONCAT(',', REPLACE(query, ' ', ','), ',') REGEXP
CONCAT(',', SUBSTRING_INDEX(@search, ' ', 1), 's?,'))
AND
(CONCAT(',', REPLACE(query, ' ', ','), ',') REGEXP
CONCAT(',', SUBSTRING_INDEX(@search, ' ', -1), 's?,'))
WHEN 2
THEN
(CONCAT(',', REPLACE(query, ' ', ','), ',') REGEXP
CONCAT(',', SUBSTRING_INDEX(@search, ' ', 1), 's?,'))
AND
(CONCAT(',', REPLACE(query, ' ', ','), ',') REGEXP
CONCAT(',', SUBSTRING_INDEX(SUBSTRING_INDEX(@search, ' ', 2), ' ', -1), 's?,'))
AND
(CONCAT(',', REPLACE(query, ' ', ','), ',') REGEXP
CONCAT(',', SUBSTRING_INDEX(@search, ' ', -1), 's?,'))
WHEN 3
THEN
(CONCAT(',', REPLACE(query, ' ', ','), ',') REGEXP
CONCAT(',', SUBSTRING_INDEX(@search, ' ', 1), 's?,'))
AND
(CONCAT(',', REPLACE(query, ' ', ','), ',') REGEXP
CONCAT(',', SUBSTRING_INDEX(SUBSTRING_INDEX(@search, ' ', 2), ' ', -1), 's?,'))
AND
(CONCAT(',', REPLACE(query, ' ', ','), ',') REGEXP
CONCAT(',', SUBSTRING_INDEX(SUBSTRING_INDEX(@search, ' ', 3), ' ', -1), 's?,'))
AND
(CONCAT(',', REPLACE(query, ' ', ','), ',') REGEXP
CONCAT(',', SUBSTRING_INDEX(@search, ' ', -1), 's?,'))
ELSE FALSE
END
;
这对于有限数量的搜索术语可能是可行的。不确定,与生成等效的 LIKE , INSTR 甚至 REGEXP 相比,这是非常明智/可取的。
如果需要调整/进一步详细说明,请发表评论。