繁体   English   中英

在数据库中搜索确切的单词(无区分大小写)

[英]Search exact word on database (none case sensitive)

我有这个查询,我用它来获取指定记录的位置。

$sq = "SELECT COUNT(*) 
         FROM items LEFT JOIN info ON items.refID = info.refID 
           WHERE info.description = :status AND items.itmName < :itm 
             ORDER BY items.itmName";
$stmt = $connect->prepare($sq);
$stmt->execute(array(':status'=>"inStock", ':itm'=>$itm));
$rslt = $stmt->fetch(PDO::FETCH_NUM);
$pos = $rslt[0]+1;

问题(举个例子):

$itm = "Mango"

我在我的数据库中有一个名为Mango的项目然后当我进行搜索时它返回Mango的正确位置为321 //正常工作

$itm = "Mangox"

如果我键入Mangox并进行搜索(Mangox不存在),它仍然会返回321的位置。

如何使搜索词与数据库中的确切项匹配(但不区分大小写)?

问题是,要获得“位置”,您要计算的所有名称都小于您要查找的名称。

因此,无论您搜索什么,只要名称小于0,它就会返回大于0的数字。

例如, $itm = "ZZZ"可能会让您获得表格中的最后位置。

另一个问题是你以后做的事情:

$pos = $rslt[0]+1;

因此,即使查询返回0 ,您仍然会将其视为位置编号1。

从另一个问题中获取的一种可能性(我没有运行它,因此它可能有一些语法问题,但一般的想法可能有效):

SELECT rank
    FROM (
        SELECT @rn:=@rn+1 AS rank, itmName
        FROM (
            SELECT items.itmName
            FROM items LEFT JOIN info ON items.refID = info.refID 
            WHERE info.description = :status AND items.itmName <= :itm 
            ORDER BY items.itmName
        ) t1, (SELECT @rn:=0) t2
    )
WHERE itmName = :itm

在任何情况下,您都需要处理这样一个事实,即当名称不存在时,查询现在不会返回任何数字。

当列表中找不到Mangox时,您想要返回什么结果? 您是否希望查询返回行?

不需要ORDER BY子句,因为查询返回一行。 LEFT JOIN的“外部性”由WHERE子句中的谓词否定。 (如果info.description = something ,这意味着info.description IS NOT NULL ,这意味着它将从info中没有匹配行的items中排除任何行。因此,它实际上是一个内部联接。)

要在items表中不存在指定的:itm不返回任何行 ,可以对返回零行的查询执行连接操作。

  SELECT p.pos
    FROM ( SELECT COUNT(*) AS pos
             FROM items
             JOIN info
               ON items.refID = info.refID
            WHERE info.description = :status
              AND items.itmName < :itm
         ) p
   CROSS
    JOIN (SELECT 1
            FROM items r
           WHERE r.itmName = :itm2   -- additional bind placeholder
           LIMIT 1
         ) q

对于添加的绑定占位符,您需要第二次传入$itm的值。

  $stmt->execute(array(':status'=>"inStock", ':itm'=>$itm, ':itm2'=>$itm));
  //                                                     ^^^^^^^^^^^^^^^

如果没有返回一行,则fetch将返回FALSE,因此在引用$rslt[0]之前,您需要进行额外的检查(实际上有一行)。

  $rslt = $stmt->fetch(PDO::FETCH_NUM);
  if (!$rslt) {
     // row returned
     $pos = $rslt[0]+1;
  } else {
     // fetch failed, no row returned
     // ??? do whatever you want to do when the exact word is not matched
     $pos = 0; // ???
  }

编辑

即使在传递相同值时,不同绑定占位符名称:itm2的原因是在语句中多次使用相同的绑定占位符名称(在PDO中)不能像我们预期的那样工作,如它与其他数据库接口有关。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM