创建搜索查询并根据所选复选框显示结果(难度分组结果)

时间:2012-11-20 15:15:18

标签: php mysql

我希望有一个显示多个关键字(复选框)的php页面,例如Narberth,Pembrokeshire,Carmarthenshire等区域以及其他内容。

到目前为止,我已经创建了一种方法,并在表格中单独显示数据。我遇到的问题是首先显示与多个关键字关联的行。

因此,如果用户搜索“Narberth”和“Pembrokeshire”,结果会显示任何带有这两个关键字的文档,然后是“narberth”和“pembrokshire”之后的任何关键词。

我列出了我迄今为止所做的工作代码:

<form method="post">
<table border="1px solid" width="60%">
<tr>
<td><input type="checkbox" name="keywords[]" value="1">Narberth </td>
<td><input type="checkbox" name="keywords[]" value="2">James Brothers </td>
<td><input type="checkbox" name="keywords[]" value="3">Mabinogion </td>
</tr>
<tr>
<td><input type="checkbox" name="keywords[]" value="4">Pembrokeshire </td>
<td><input type="checkbox" name="keywords[]" value="5">Pubs </td>
<td><input type="checkbox" name="keywords[]" value="6">Coastal Paths </td>
</tr>
</table>
<br>
<input type="submit" name = "submit">

<?php
if (isset($_POST['submit'])) {

foreach( $_REQUEST['keywords'] as $keywordID )
{
$result = mysql_query("SELECT * FROM tbl_index m
inner join tbl_filekeywords r on m.file_id = r.file_id
where r.keyword_id = '".$keywordID."'");

$keywordname = mysql_query ("SELECT keyword FROM tbl_keywords WHERE keyword_id = '".$keywordID."'");
$KeywordName = mysql_fetch_row($keywordname);
$KeywordName = $KeywordName[0];

echo "<table border='1' width='50%'>
<th colspan='2'>".$KeywordName."</th>
<tr>
<th>File ID</th>
<th>Filename</th>
</tr>";

while($row = mysql_fetch_array($result)){
echo "<tr>";
echo "<td>" . $row['file_id'] . "</td>";
echo "<td>" . $row['file'] . "</td>";
echo "</tr>";
}
echo "</table><br>";
mysql_free_result($result);
}
}?>
PS还有另一个我开发的替代方案,它将所有文件整合到一个表中,这很好,但我仍然希望停止为每个关键字多次出现相同的文件,而宁愿优先考虑具有多个关键字的文件并显示在顶部。

<?php
if(isset($_POST['keywords']) && !empty($_POST['keywords'])){
foreach($_POST['keywords'] as $key=>$value){
if($value==1) $keywords[] = "keyword_id='".mysql_escape_string($key)."'";
}
$keywords = implode(' OR ', $keywords);
}
$query = "SELECT * FROM tbl_index m inner join tbl_filekeywords r on m.file_id = r.file_id WHERE $keywords";
$result = mysql_query($query);

echo "<table border='1' width='50%'>
<tr>
<th>File ID</th>
<th>Filename</th>
<th>Keyword_ID</th>
</tr>";

while($row = mysql_fetch_array($result)){
echo "<tr>";
echo "<td>" . $row['file_id'] . "</td>";
echo "<td>" . $row['file'] . "</td>";
echo "<td>" . $row['keyword_id'] . "</td>";
echo "</tr>";
}
echo "</table><br>";
mysql_free_result($result);
?>

最后表格设置如下:

tbl_index : file_id, file

tbl_keywords : keyword_id, keyword

tbl_filekeywords : file_id, keyword_id

1 个答案:

答案 0 :(得分:1)

首先,欢迎来到SO。答案延迟是由于非综合问题。在接下来的问题中,请记住仅包含相关的相关代码。

让我们假设tbl_indextbl_filekeywords表格为1:N关系。

首先,在php中,您可以将$keywords作为所选关键字的字符串列表示例:

$keywords = " 1, 5, 12,  24"

现在你可以用这种方式对tbl_filekeywords进行排名。我们将rank view命名为

select 
  r.file_id, 
  sum( case when r.keyword_id in ( $keywords  ) then 1 else 0 end ) as rank
from
  tbl_filekeywords r
group by 
  r.file_id

最后一步是将rank view加入tbl_index:

   select t.*
   from 
     tbl_index t left outer join
     ( HERE PREVIUS QUERY ) r
          on r.file_id = t.file_id
   order by
     coalesce( r.rank, 0 )

让我们知道这是否运行,它是一个解决方案。如果没有,请解释我们如何改进答案!

编辑过期OP评论

我没有您的数据库架构,但似乎file_idtbl_index的PK。如果是这种情况,查询不会产生重复。请注意,由于group by子句,第一个查询rank view仅对每个file_id都有一行。因为这样,连接不会产生重复。对我来说,最后的问题是:

   select t.*
   from 
     tbl_index t inner join                 <--No dups
     ( 
       select 
         r.file_id, 
         count(*) as rank
       from
         tbl_filekeywords r
       where
         r.keyword_id in ( $keywords  )
       group by 
         r.file_id                          <--No dups
     ) r2
          on r2.file_id = t.file_id
   order by
      r2.rank