SQL - 在子句中使用LIKE时根据优先级排序数据

时间:2016-07-18 09:39:54

标签: php mysql sql sorting

谷歌搜索后,在like

中使用clause时,根据优先级排序数据无法找到我的答案

我使用以下查询来排序和查看数据:

SELECT    i.name,i.add_time,round(i.price),s.store_address
FROM      store_items i,stores s
WHERE     i.store_id = s.store_id 
AND       (lower(i.name) LIKE '%samsung glaxy%'
   OR lower(i.name) LIKE '%samsung%'
   OR lower(i.name) LIKE '%glaxy%')
ORDER BY  i.price ASC LIMIT 0,25

我如何首先为三星Galaxy 第一个like运算符排序结果行作为优先级,然后为三星 Galaxy 作为第二优先事项?

请注意:

第一优先级表示应首先显示结果行,第二优先级表示其他结果行应显示在

之后

我必须在我的PHP函数中使用它。

@ 10086'回答我无法将其纳入PHP CODE

我的PHP代码是:

$sort = $_COOKIE['sort'];
$price_sort = $_COOKIE['price_sort'];
$currency_value = $_COOKIE['currency_value'];

if (!isset($_GET['number'])) {
       $limit = 0;
}else{
      $limit = filter_var($_GET['number'], FILTER_SANITIZE_NUMBER_INT);
}

 $keyword_exp = explode(" ", $keyword); //separating keywords
 $like = ""; //for use like clause for every keyword
 $case = ""; // for priority selection case in query order
 $case_inc = 2;
 foreach ($keyword_exp as $value) {
          $like .= "AND lower(i.name) like '%$value%'"; 
          $case .= "WHEN lower(i.name) like '%$value%' THEN $case_inc";
          $case_inc += 1;
 } 
  //query performing to show result
  $sql_query = "SELECT i.name 'title',i.add_time 'time',round(i.price) 'price',round(i.new_price) 'new_price',s.store_address 'address' FROM store_items i,stores s WHERE i.store_id = s.store_id $like ORDER BY CASE WHEN lower(i.name) LIKE '%$keyword%' THEN 1 $case END ASC LIMIT 0,25";
  $query = mysql_query($sql_query) or die(mysql_error());
  while ($row = mysql_fetch_array($query)) :
               extract($row);
  endwhile;

我在PHP代码中的SQL查询给出了以下错误:

  

您的SQL语法有错误;检查与您的MariaDB服务器版本对应的手册,以获得正确的语法,以便在' lower(i.name)附近使用'%翻新%'那么3结束ASC限制0,25'在第1行

2 个答案:

答案 0 :(得分:1)

使用CASE WHEN

SELECT    i.name,i.add_time,round(i.price),s.store_address
FROM      store_items i,stores s
WHERE     i.store_id = s.store_id 
AND       (lower(i.name) LIKE '%samsung glaxy%' OR lower(i.name) LIKE '%samsung%' OR lower(i.name) LIKE '%glaxy%')
ORDER BY
CASE WHEN lower(i.name) LIKE '%samsung glaxy%' THEN 1
     WHEN lower(i.name) LIKE '%samsung%' THEN 2
     WHEN lower(i.name) LIKE '%glaxy%' THEN 3
     ELSE 4 END,
i.price ASC
LIMIT 0,25

答案 1 :(得分:1)

您的查询不会尽可能快,因为:

  1. lower已经不区分大小写时,您使用LIKE函数。 select 'a' LIKE 'A'将返回true
  2. 使用列作为WHERE中函数的参数会强制服务器绕过其索引并处理该行:例如:lower(i.name)。通常应该避免这种情况
  3. 如果你有MySQL 5.6+,如果store_items.name类型为 CHAR VARCHAR TEXT ,那么添加一个 FULLTEXT 指向您的name列的索引,以针对文本搜索进行优化。

    ALTER TABLE store_items ADD FULLTEXT fulltext_name (name);
    

    然后修改您的查询以使用MATCH...AGAINST语法:

    SELECT i.name,i.add_time,round(i.price),s.store_address
    FROM store_items i JOIN stores s ON i.store_id = s.store_id
    WHERE MATCH(i.name) AGAINST('samsung galaxy')
    

    此搜索将返回至少包含两个单词samsunggalaxy之一的所有行。两个单词的行在结果集中会更高。

    From the docs

      

    MATCH()采用逗号分隔的列表来命名列   搜索。 AGAINST需要一个字符串来搜索和一个可选项   修饰符,指示要执行的搜索类型

         

    ...

         

    全文索引只能用于MyISAM表。 (在MySQL 5.6中   并且,它们也可以与InnoDB表一起使用。)全文索引   只能为CHAR,VARCHAR或TEXT列创建