匹配多个字符串中的一个的SQL查询

12

我有以下表格数据:

+----------------------+----------------------------------------------------------+--------------+
| subscriber_fields_id | name                                                     | field_type   |
+----------------------+----------------------------------------------------------+--------------+
|                  143 | Peshawar/Islamabad/Lahore/Swat/Mardan/Karachi            | Job Location |
|                  146 | Karachi                                                  | Job Location |
|                  147 | Lahore and Karachi                                       | Job Location |
|                  149 | Karachi, Mirpur Khas, Sukkur, Layyah, Gilgit, Charsaddah | Job Location |
|                  152 | Islamabad or Lahore                                      | Job Location |
|                  155 | Islamabad                                                | Job Location |
|                  157 | 7 Districts of Sindh and Karachi                         | Job Location |
+----------------------+----------------------------------------------------------+--------------+

我的查询是:

select * from subscriberfields
where  name like '%Khairpur,Islamabad,Karachi%';

结果:

+----------------------+-----------------------------------------------+--------------+
| subscriber_fields_id | name                                          | field_type   |
+----------------------+-----------------------------------------------+--------------+
|                  143 | Peshawar/Islamabad/Lahore/Swat/Mardan/Karachi | Job Location |
|                  152 | Islamabad or Lahore                           | Job Location |
|                  155 | Islamabad                                     | Job Location |
+----------------------+-----------------------------------------------+--------------+

它应该返回所有名称中包含伊斯兰堡、开普尔或卡拉奇的行,但它没有。


你想使用 WHERE name LIKE '%Khairpur%' OR name LIKE ... 进行查询。然而,这种方式不是可搜索的,因此需要进行全表扫描——随着表格大小的增长,效率将变得非常低下。你应该考虑使用全文搜索代替。 - eggyal
你尝试过像我在答案中建议的那样使用 SIMILAR TO 吗? - benscabbia
@gudthing:永远不要使用SIMILAR TO,它是一个完全无意义的语句 - 总有更好的选项。我添加了一个答案。 - Erwin Brandstetter
5个回答

25
为了找到一个合适的解决方案,要么规范化你的数据库设计,要么考虑全文搜索
为了快速解决手头的问题,可以使用一个正则表达式匹配(~或三个简单的LIKE表达式。
SELECT *
FROM   subscriberfields 
WHERE  name ~ '(Khairpur|Islamabad|Karachi)';

或者:

WHERE (name LIKE '%Khairpur%'
    OR name LIKE '%Islamabad%'
    OR name LIKE '%Karachi%')

.. 可以像 Mario 在他的回答中展示的那样进行压缩。或者更短,可以使用数组文字:

WHERE name LIKE ANY ('{%Khairpur%, %Islamabad%, %Karachi%}');

但是在现代的Postgres中,正则表达式匹配获得相同的查询计划(可以使用相同的trigram索引),并且更短。参见:

  • {{link1:PostgreSQL LIKE查询性能变化}}

或者使用~*ILIKE进行不区分大小写匹配。

因为另一个答案建议过:永远不要使用SIMILAR TO

  • {{link2:使用SIMILAR TO进行正则表达式匹配?}}
  • {{link3:使用LIKE、SIMILAR TO或正则表达式进行模式匹配}}

5

3

尝试使用以下代码中的SIMILAR TO

SELECT * FROM subscriberfields 
WHERE name SIMILAR TO '%(Khairpur|Islamabad|Karachi)%';

此外,您应该了解数据库规范化。您的设计肯定可以和应该得到改进。


0
在MySQL中,尝试使用正则表达式"REGEXP"和操作符|,它的作用类似于OR。
SELECT * FROM subscriberfields  WHERE  name REGEXP 'Khairpur|Islamabad|Karachi';

因此,您将获得包含这些单词中至少一个的结果。

或者,如果您想要包含所有单词的结果,请使用:

SELECT * FROM subscriberfields  WHERE  name REGEXP '(?=.*Khairpur)(?=.*Islamabad)(?=.*Karachi)';

在服务器版本10 MariaDB和PHP 8上可与MySQL一起使用

如果想了解更多关于REGEXP的内容,请尝试:

https://www.geeksforgeeks.org/mysql-regular-expressions-regexp/ https://www.freecodecamp.org/news/sql-contains-string-sql-regex-example-query/

有很多博客提供正则表达式的例子,但并不是每个人都会给你可以使用的所有模式和值,但对于初学者来说,可以先看看这些。


-1

在WHERE子句中使用OR,例如:

select * from subscriberfields where name like '%Khairpur%' OR name like '%Islamabad%' OR name like '%Karachi%';

希望它能正常工作。

不行,这个值是从数据库中获取的,我无法通过逗号进行分割,因为有时它会被分割成逗号、空格、斜杠、破折号等。 - Muhammad Taqi
1
@MTaqi:这听起来确实是一个非常糟糕的数据库设计。你可能想要阅读一下数据库规范化,并且也可以看一下在数据库列中存储分隔列表真的那么糟糕吗? - eggyal
在这种情况下,您真的需要考虑使用FULLTEXT搜索,正如eggyal所建议的那样。 - BabyDuck

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接