0

请我对mysql完全陌生,我的问题是:

我有一个名为“cong”的表,其中包含以下列(id、sort_code、pin、name、state、lga、zip、address、min、min_photo、sec、min_phone、sec_phone),其中包含所有会众。

列 (state, lga) 包含表“states”和“local_govt”中的 id。

“states”表具有以下列(id、country_id、name),“local_govt”表具有以下列(id、country_id、state_id、name)。

我想对“cong”表进行搜索,该表应该在“state”和“local_govt”表中搜索匹配项,下面是我编写的搜索功能:

      <?php
      function find_cong($term) {
      $query = "SELECT * FROM cong";
      $query .= " WHERE state rLIKE
      (SELECT id FROM states WHERE upper(name) rLIKE '{$term}')";
      $query .= " OR lga rLIKE
      (SELECT id FROM local_govt WHERE upper(name) rLIKE '{$term}')";
      $query .= " OR upper(name) rLIKE '{$term}'";
      $query .= " OR upper(address) rLIKE '{$term}'";
      $query .= " OR upper(sort_code) rLIKE '{$term}'";
      $query .= " OR upper(pin) rLIKE '{$term}'";
      $query .= " OR upper(zip) rLIKE '{$term}'";
      $query .= " OR upper(min) rLIKE '{$term}'";
      $query .= " OR upper(sec) rLIKE '{$term}'";
      $query .= " OR upper(min_phone) rLIKE '{$term}'";
      $query .= " OR upper(sec_phone) rLIKE '{$term}'";
      $result = mysql_query($query);
      confirm_query($result);
      return $result;
      }

      function confirm_query($query) {
          if (!$query) {
             die("Database query failed : " . mysql_error());
          }
      }

      ?>

现在的问题是,它搜索了一些术语并得出了准确的结果,但是对于一些特定的术语,如 local_govt 和州名,它会弹出一个错误:(数据库查询失败:子查询返回超过 1 行)

请我需要你的帮助,因为我不知道如何更好地编写代码。谢谢。

4

2 回答 2

0

WHERE 语句的stateslocal_govt部分中有子查询。据推测,对于给定值的行$term,这些查询将返回多于一行的结果集。因为您正在使用rLIKE,它希望针对一个值(而不是多个)进行评估,所以整个查询将出错。

相反,重构如下:

$query .= " WHERE state IN (SELECT id FROM states WHERE upper(name) rLIKE '{$term}')";
$query .= " OR lga IN (SELECT id FROM local_govt WHERE upper(name) rLIKE '{$term}')";

这将解决这种意外情况。

请注意,编写的查询不太可能非常高效。由于您正在扫描许多不同的列,因此最好不要在此处使用正则表达式,因为优化器将无法利用索引。理想情况下,将其减少到一个常数,以便您可以使用:

SELECT * FROM cong WHERE $term IN (upper(name), upper(address)...)

但鉴于您的要求,这可能是不可能的。如果是这种情况,我可能会查看您的程序设计并尝试将查询拆分为从应用程序端最多针对一列的查找,例如:

SELECT * FROM cong WHERE $term rLIKE upper(NAME)
于 2013-09-23T16:27:48.993 回答
0

这里有错误:

$query .= " WHERE state rLIKE
      (SELECT id FROM states WHERE upper(name) rLIKE '{$term}')";
      $query .= " OR lga rLIKE
      (SELECT id FROM local_govt WHERE upper(name) rLIKE '{$term}')";

rlike是一个正则表达式,但最终归结为值的直接比较。您的子查询返回多行,因此以重写的方式,您的查询将更像:

WHERE state = a,b,c,...
 OR lga  = z,y,x,...

您正在尝试对多个值进行相等性测试,这会使数据库感到困惑。相等性测试适用于 SINGLE 值,例如a=b, not a=b,c

于 2013-09-23T16:28:32.717 回答