MySQLi WHERE LIKE 多个条件

Posted

技术标签:

【中文标题】MySQLi WHERE LIKE 多个条件【英文标题】:MySQLi WHERE LIKE multiple criteria 【发布时间】:2015-05-28 18:05:18 【问题描述】:

我有以下示例表和属性:

---------------------------
|  Name  |       Town     |
---------------------------
| Name 1 |      POOLE     |
| Name 2 | POOLE/WALLASEY |
| Name 3 | POOLE/WALLASEY |
| Name 4 |      POOLE     |
---------------------------

我在 php 中使用以下 SQL 语句来检索行:

SELECT * FROM `table` WHERE `Town` LIKE '%".$global->getPlayerTown()."%'

给定条件POOLE,数据库返回:

---------------------------
|  Name  |       Town     |
---------------------------
| Name 1 |      POOLE     |
| Name 2 | POOLE/WALLASEY |
| Name 3 | POOLE/WALLASEY |
| Name 4 |      POOLE     |
---------------------------

但是,当使用条件 POOLE/WALLASEY 时,查询返回:

---------------------------
|  Name  |       Town     |
---------------------------
| Name 2 | POOLE/WALLASEY |
| Name 3 | POOLE/WALLASEY |
---------------------------

如何智能地告诉 PHP 在一个查询中将字符串拆分为单独的条件(即POOLEWALLASEY),以便查询检索所有行?

【问题讨论】:

/ 上分解城镇字符串,用分解的部分构建单独的like 子句,构建新的 sql 字符串...或者只是规范化表中的数据 @MarcB 表没有完全标准化,我理解。但是,你能给我举一个爆炸查询的例子吗? 投票支持规范化。这样,您在搜索数据库时(显然)受到限制。 它会以 where foo like '%poole%' (and/or, depending on your needs) foo like '%wallasey%' 结尾,例如搜索字符串中的每个城镇名称都有一个 like 子句。 唯一的问题是POOLEVILLEPOOLE 会匹配。呸。此外,如果用户输入的城镇实际上有多个由斜线分隔的名称(例如,使用国家/地区Netherlands/Holland)怎么办?这不太可能,但可能。另请参阅此问题:***.com/questions/471914/… 【参考方案1】:
SELECT * FROM `table` WHERE `town` REGEXP 'POOLE|WALLASEY';

这将匹配具有一个或多个 POOLE 或 WALLASEY 实例的任何行。

对于 PHP 方面,取决于您的数据集中有多少种分隔符(在本例中为“/”),它可能会很快变得相当混乱。 但是将 '/' 替换为 '|'在 getPlayerTown() 中似乎是一种方法。

关于性能,我不确定 REGEXP 与 LIKE 相比如何。

https://dev.mysql.com/doc/refman/5.7/en/regexp.html

【讨论】:

幸好我们只有/【参考方案2】:

这是一系列常见问题的迭代:如果我在一个字段中有多个数据,我如何选择一个数据?

一如既往,答案是:你不知道。

这有很多原因,但最重要的原因之一是性能:基本上LIKE '%...' 不能使用索引。对于少数测试行,这可能没问题,但在扩展时很快就会成为问题。

唯一可靠的方法是

要么规范化你的数据 或使用全文索引

在您的情况下,我强烈支持标准化:创建一个 towns 表,然后通过连接表将其链接到玩家。您现在可以搜索任何使用完整索引的城镇,通过连接找到玩家。

【讨论】:

感谢您的输入,我给出的示例是我的表格的精简版本,数据不受我控制,因为是从 csv 导入的,所以我无法规范化。跨度> 【参考方案3】:

正如 Marc B 所说,使用explode。

<?php
$array = explode("/",$global->getPlayerTown());

foreach($array as $Town)
  $list = $list ."'%" .$Town ."%', ";


$SQL = "SELECT * FROM `table` WHERE `Town` LIKE ANY(" .$list .")";
?>

请走智能路线并规范化您的数据。这个想法可能有效,但这并不意味着它是最佳选择。

【讨论】:

旁注:链接到官方文档可能比 w3schools 更好:php.net/explode @Mike 是的,我是,谢谢你抓住这个哈哈。修好了。 @Ryan_W4588,刚刚尝试过,它返回一个空结果?【参考方案4】:

您可以爆炸城镇,然后循环遍历它们并像这样构建查询:

$towns = explode('/', $global->getPlayerTown());
$first = true;
$like_sql = '';
foreach($towns as $town) 
    $like_sql .= $first ? ' WHERE ' : ' OR ';
    $like_sql .= "`Town` LIKE '%$town%'";
    $first = false;

$query = "SELECT * FROM `table` $like_sql";

不过,我建议您对数据进行规范化,并使用单独的 towns 表和 user_town 数据透视表。

【讨论】:

以上是关于MySQLi WHERE LIKE 多个条件的主要内容,如果未能解决你的问题,请参考以下文章

如何在 mysqli 准备语句中使用多个内部连接和多个 WHERE 子句? [复制]

mybatis查询中多个条件where后面怎么写

使用 mysqli_stmt_prepare 准备查询,在 WHERE 之后绑定逻辑条件

mysql原生语句where数组条件查询

如何根据 WHERE 条件使用 mysqli 进行 SELECT 和 DELETE 和 RETURN 单行

mysql中on,in,as,where如何用,意思是啥?