2

Narberth、Pembrokeshire、Carmarthenshire などの地域やその他のものなど、複数のキーワード (チェックボックス) を表示する php ページが必要です。

これまでのところ、これを行い、データをテーブルに個別に表示する方法を作成しました。私が問題を抱えているのは、最初に複数のキーワードが関連付けられた行を表示することです。

したがって、ユーザーが "Narberth" と "Pembrokshire" を検索した場合、結果には、これらの両方のキーワードが最初に含まれるドキュメントが表示され、次に "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すべてのファイルを1つのテーブルにまとめて開発した別の代替手段がありますが、これは問題ありませんが、キーワードごとに同じファイルが複数回表示されるのを止めたいのですが、複数のキーワードを持つファイルを優先して表示したいと考えています上。

<?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
4

1 に答える 1

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_idPK のようですtbl_index。この場合、クエリは重複を生成しません。最初のクエリ には、 group by 句がrank viewあるため、それぞれの行しかないことに注意してください。file_idこのため、 join は重複を生成しません。私にとって最後のクエリは次のとおりです。

   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
于 2012-11-20T15:41:57.680 に答える