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

时间:2015-06-30 03:26:45

标签: php mysql pdo

我已经得到了这个查询,用于获取指定记录的位置。

$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。

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

2 个答案:

答案 0 :(得分:0)

问题在于获得&#34;位置&#34;你正在计算所有小于你正在寻找的名字。

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

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

另一个问题是你以后会这样做:

$pos = $rslt[0]+1;

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

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

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

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

答案 1 :(得分:0)

如果在列表中找不到Mangox,您希望返回什么结果?您是否希望查询返回一行?

不需要ORDER BY子句,因为查询返回一行。 LEFT JOIN中的谓词否定了WHERE的“外部性”。 (如果info.description = something,则表示info.description IS NOT NULL,这意味着它会排除items中没有来自info的匹配行的任何行。所以,它实际上是内连接。)

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

  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中)不起作用正如我们所期望的那样,与其他数据库接口一样。