【问题标题】:PHP SQL SELECT where like search item with multiple wordsPHP SQL SELECT where like search item with multiple words
【发布时间】:2011-04-06 23:38:09
【问题描述】:

我有一个 select where like 查询表单,如下所示:

<?php 
$bucketsearch = sanitizeone($_POST["bucketsearch"], "plain");
$bucketsearch = strip_word_html($bucketsearch);
?>

 if(isset($_POST['search'])){
                  $result=MYSQL_QUERY( "SELECT * FROM buckets where bucketname like '%$bucketsearch%' order by bucketname");
              }else{
              $result=MYSQL_QUERY( "SELECT * FROM buckets order by bucketname");
          }

我的问题是,如果有人搜索例如“apple and pear”,我没有得到任何包含任何单词的结果,我只能让它返回包含所有单词的结果(以及 1 个结果)。

谁能帮我让这个搜索更通用一点? 提前致谢。

【问题讨论】:

    标签: php sql mysql select


    【解决方案1】:

    所以您想要使用输入的每个单词而不是确切的字符串进行 AND 搜索?这样的事情怎么样:

    $searchTerms = explode(' ', $bucketsearch);
    $searchTermBits = array();
    foreach ($searchTerms as $term) {
        $term = trim($term);
        if (!empty($term)) {
            $searchTermBits[] = "bucketname LIKE '%$term%'";
        }
    }
    
    ...
    
    $result = mysql_query("SELECT * FROM buckets WHERE ".implode(' AND ', $searchTermBits).");
    

    这会给你一个类似的查询:

    SELECT * FROM buckets WHERE bucketname LIKE '%apple%' AND bucketname LIKE '%and%' AND bucketname LIKE '%pear%'
    

    如果您想匹配任何搜索词而不是全部,请将 AND 更改为 OR。进一步的改进可能包括定义一些停用词,如“和”,以提供更好的结果。

    【讨论】:

    • 蒂姆,谢谢!我玩了大约 30 分钟,我复制了我的页面来测试它,无法弄清楚为什么它不起作用,对所有内容进行了大量检查,然后意识到 Dreamweaver 在我的输入末尾添加了“2”姓名!!!呸。我将其更改为 OR,它实现了一个梦想!谢谢你。现在就去寻找一个删除停用词的功能。谢谢您的帮助!! :)
    • 对于任何阅读此内容的 laravel ppl,请查看:gist.github.com/clouddueling/4967617
    • 我只想补充一点,当使用 OR 模式时,必须将整个查询条件括在括号 () 中,因为可能会发生意外结果(尽管您不会知道,因为每次都不会出现 MySQL 错误瑟)。我从不相关的类别中得到结果,即使在单独的 AND 条件中指定了特定类别。例如,在 Tim 的回答中替换上述内容: implode(' OR ', $searchTermBits) 部分为 '(' . implode(' OR ', $searchTermBits) . ')'
    【解决方案2】:

    我认为最好的解决方案是使用正则表达式。它是最干净的,可能也是最有效的。所有常用的数据库引擎都支持正则表达式。

    在 MySQL 中有 RLIKE 运算符,因此您的查询将类似于:

    SELECT * FROM buckets WHERE bucketname RLIKE "(?=.*apple)(?=.*and)(?=.*pear)"
    

    没有测试,希望我的表达方式适合MySQL正则表达式“方言”。

    有关 MySql 正则表达式支持的更多信息:
    http://dev.mysql.com/doc/refman/5.1/en/regexp.html#operator_regexp

    【讨论】:

      【解决方案3】:

      对于您的简单案例,您可以将“and”替换为“%”(但我猜您正在寻找更全面的答案。(这也是特定于订单的,因为苹果必须在梨之前。)

      【讨论】:

        【解决方案4】:

        呃。这不是我认为的最佳解决方案,但您可以将单词分解成一个数组并将它们循环成多个 LIKES。做一些替换以抽出 AND、OR 等,然后运行爆炸。

        然后循环。

        $sql = SELECT * from Buckets where";

        循环数组, $sql .= "bucketname LIKE '%" 。 $arrayEl[i] 。 "% OR'。只需确保在最后一次迭代中不包含最后一个 OR 或附加最后一行 0=1 等。

        不优雅,效率不高,但在这种情况下它会起作用。老实说,如果它是一个文本字段,你最好运行全文搜索。

        【讨论】:

          【解决方案5】:

          我想要在 MySQL 数据库中进行多词搜索时使用基本 SQL。所以我想出了以下内容。

          $terms=explode(" ",$search);
          $count=count($terms);
          $sql="SELECT * FROM product WHERE";                     
          for($i=0;$i<$count;$i++)
          {
              if($i!=$count-1)
                  $sql = $sql.
                  " (pname LIKE '%$terms[$i]%' OR category LIKE '%$terms[$i]%' OR    
                    sub_category LIKE '%$terms[$i]%' OR 
                    description LIKE '%$terms[$i]%') AND ";
              else
                  $sql = $sql.
                  "(pname LIKE '%$terms[$i]%' OR category LIKE '%$terms[$i]%' OR 
                   sub_category LIKE '%$terms[$i]%' OR 
                   description LIKE '%$terms[$i]%')";
          }    
          

          【讨论】:

            【解决方案6】:

            您可以将“apple and pear”拆分为 2 个字符串; “苹果”和“梨”。也许,那你可以做WHERE bucketname LIKE '%apple%' OR bucketname LIKE '%pear%'。我不知道这是否有帮助。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2011-11-28
              • 2013-05-01
              • 2011-01-21
              • 1970-01-01
              • 2017-12-07
              • 2018-11-14
              • 2018-08-24
              相关资源
              最近更新 更多