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 在一个查询中将字符串拆分为单独的条件(即POOLE
和WALLASEY
),以便查询检索所有行?
【问题讨论】:
在/
上分解城镇字符串,用分解的部分构建单独的like
子句,构建新的 sql 字符串...或者只是规范化表中的数据
@MarcB 表没有完全标准化,我理解。但是,你能给我举一个爆炸查询的例子吗?
投票支持规范化。这样,您在搜索数据库时(显然)受到限制。
它会以 where foo like '%poole%' (and/or, depending on your needs) foo like '%wallasey%'
结尾,例如搜索字符串中的每个城镇名称都有一个 like
子句。
唯一的问题是POOLEVILLE
和POOLE
会匹配。呸。此外,如果用户输入的城镇实际上有多个由斜线分隔的名称(例如,使用国家/地区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 子句? [复制]
使用 mysqli_stmt_prepare 准备查询,在 WHERE 之后绑定逻辑条件