[英]Php MySql Query with Multiple Keyword for Multiple Fields
我正在使用php和mySql創建一個Web應用程序。
它基本上是一個帶有單個文本框的簡單搜索表單。
用戶輸入可以是關鍵字的組合,我在string_ireplace()
之后使用php explode()
函數。
現在我想在一個表中搜索每個關鍵字(比如val 1,val 2,..... val n)對每個字段(比如提交1,提交2,......字段n)。
我覺得我將不得不使用多個for循環 - 為每個值搜索所有字段。
但是我如何根據相關性對結果進行排序,即。 匹配所有值的記錄將首先出現,依此類推。
由於此表排序不在數據庫級別,因此我無法使用ORDER BY
子句。
編輯:好的。 我想我必須詳細解釋我在尋找什么以及我取得了什么。 我編寫的代碼如下,它幾乎符合我的目的,但看起來非常耗時(執行)。
<?php
//$str = mysql_real_escape_string($_GET['searchText']);
$str = "val1, val2, val3";
$str = trim($str);
// check for an empty string and display a message.
if ($str == "") {
$resultmsg = "<p>Search Error: Please enter a search keyword...</p>" ;
}
$str = explode(",",$str);
//Create array for all fields
$fields = array("filed1","filed2","filed3","filed4");
$condition = "";
for ($j=0;$j<count($str);$j++){
for ($i=0;$i<count($fields);$i++){
$condition = $condition.$fields[$i]." = '".$str[$j]."' OR ";
}
$condition = rtrim($condition, " OR");
$condition = $condition.") AND (";
}
$condition = rtrim($condition, " AND (");
$sql = "SELECT * FROM TABLE WHERE (".$condition;
echo $sql;
echo "<br /><hr>";
$condition = "";
for ($j=0;$j<count($str);$j++){
for ($i=0;$i<count($fields);$i++){
$condition = $condition.$fields[$i]." = '%".$str[$j]."%' OR ";
}
$condition = rtrim($condition, " OR");
$condition = $condition.") AND (";
}
$condition = rtrim($condition, " AND (");
//$condition = str_replace("="," LIKE ",$condition);
$sql= "SELECT * FROM TABLE WHERE (".$condition;
echo $sql;
echo "<br /><hr>";
//testing
if (count($str)==3){
$condition = "";
for ($j=0;$j<count($str)-1;$j++){
for ($i=0;$i<count($fields);$i++){
$condition = $condition.$fields[$i]." = '%".$str[$j]."%' OR ";
}
$condition = rtrim($condition, " OR");
$condition = $condition.") AND (";
}
$condition = rtrim($condition, " AND (");
//$condition = str_replace("="," LIKE ",$condition);
$sql= "SELECT * FROM TABLE WHERE (".$condition;
echo "<strong>Matching ".$str[0]." AND ".$str[1]."<br /></strong>";
echo $sql;
echo "<br /><hr>";
$condition = "";
for ($j=1;$j<count($str);$j++){
for ($i=0;$i<count($fields);$i++){
$condition = $condition.$fields[$i]." = '%".$str[$j]."%' OR ";
}
$condition = rtrim($condition, " OR");
$condition = $condition.") AND (";
}
$condition = rtrim($condition, " AND (");
//$condition = str_replace("="," LIKE ",$condition);
$sql= "SELECT * FROM TABLE WHERE (".$condition;
echo "<strong>Matching ".$str[1]." AND ".$str[2]."<br /></strong>";
echo $sql;
echo "<br /><hr>";
$condition = "";
for ($j=0;$j<count($str);$j=$j+2){
for ($i=0;$i<count($fields);$i++){
$condition = $condition.$fields[$i]." = '%".$str[$j]."%' OR ";
}
$condition = rtrim($condition, " OR");
$condition = $condition.") AND (";
}
$condition = rtrim($condition, " AND (");
//$condition = str_replace("="," LIKE ",$condition);
$sql= "SELECT * FROM TABLE> WHERE (".$condition;
echo "<strong>Matching ".$str[2]." AND ".$str[0]."<br /></strong>";
echo $sql;
echo "<br /><hr>";
}
?>
我得到的輸出如下:
完全匹配所有值
SELECT * FROM TABLE WHERE(filed1 ='val1'或filed2 ='val1'或filed3 ='val1'或filed4 ='val1')AND(filed1 ='val2'或filed2 ='val2'或filed3 ='val2'OR filed4 ='val2')AND(filed1 ='val3'或者filed2 ='val3'或者filed3 ='val3'或者filed4 ='val3')
匹配所有值PARTIALLY
SELECT * FROM TABLE WHERE(filed1 ='%val1%'OR filed2 ='%val1%'OR filed3 ='%val1%'OR filed4 ='%val1%')AND(filed1 ='%val2%'OR filed2 = '%val2%'OR filed3 ='%val2%'OR filed4 ='%val2%')AND(filed1 ='%val3%'OR filed2 ='%val3%'OR filed3 ='%val3%'OR filed4 = '%val3%')
匹配val1和val2
SELECT * FROM TABLE WHERE(filed1 ='%val1%'OR filed2 ='%val1%'OR filed3 ='%val1%'OR filed4 ='%val1%')AND(filed1 ='%val2%'OR filed2 = '%val2%'或已提交3 ='%val2%'或已提交4 ='%val2%')
匹配val2和val3
SELECT * FROM TABLE WHERE(filed1 ='%val2%'OR filed2 ='%val2%'OR filed3 ='%val2%'OR filed4 ='%val2%')AND(filed1 ='%val3%'OR filed2 = '%val3%'OR filed3 ='%val3%'OR filed4 ='%val3%')
匹配val3和val1
SELECT * FROM TABLE WHERE(filed1 ='%val1%'OR filed2 ='%val1%'OR filed3 ='%val1%'OR filed4 ='%val1%')AND(filed1 ='%val3%'OR filed2 = '%val3%'OR filed3 ='%val3%'OR filed4 ='%val3%')
我現在可以繼續將獲取的數據附加到我的結果表中。 但不知怎的,我不覺得這是一個聰明的解決方案。 此外,我對搜索值的數量有限制(例如,此處為3)。 我希望我能夠解釋我到底在尋找什么。
這是一個答案,它處理可伸縮性問題(限制用戶可以搜索的關鍵字數量)和按相關性排序(每個地圖匹配關鍵字的數量)。 我刪除了檢查空值的內容,但我添加了一些內容; 閱讀評論看看是什么。 沒有測試過,所以我不知道它的表現如何......
<?php
$str = preg_split('/[\s,\+]+/', $str); // splits $str into individual words when
// it finds spaces, commas, and/or plus
// signs. This way, you won't have to
// force users to use plus signs
$fields = array('field1', 'field2', 'field3', 'field4');
foreach ($keywords as $i => $keyword) {
// escapes and quotes those keywords to prevent against injection attack
$keywords[$i] = '"' . mysql_real_escape_string($keyword) . '"';
}
// concatenates the keywords into one string that we can use as a set in
// MySQL's IN() clause
$keywords = implode(',', $keywords);
$fieldSearchQueries = array ();
foreach ($fields as $thisField) {
// here's the IN() clause, checking each field against the set of keywords
$fieldSearchqueries[] = 'CASE WHEN ' . $thisField . ' IN (' . $keywords . ')'
. ' THEN 1 ELSE 0 END';
}
$query = 'SELECT *, ' . implode(' + ' $fieldSearchQueries) . ' AS rank '
. 'FROM TABLE WHERE rank > 0 ORDER BY rank';
?>
這應該創建一個這樣的查詢:
SELECT *,
CASE WHEN field1 IN ('India', 'Rainfall', 'English') THEN 1 ELSE 0 END
+ CASE WHEN field2 IN ('India', 'Rainfall', 'English') THEN 1 ELSE 0 END
+ CASE WHEN field3 IN ('India', 'Rainfall', 'English') THEN 1 ELSE 0 END
+ CASE WHEN field4 IN ('India', 'Rainfall', 'English') THEN 1 ELSE 0 END
AS rank
FROM TABLE
WHERE rank > 0
ORDER BY rank
我剛才了解了CASE WHEN
,從這個答案來看幾乎是一個相同的問題。 我設置的方式是,如果field1
在關鍵字中,則應返回1,如果field2
在關鍵字中,則返回1,依此類推。 這會給你rank
,一個你可以排序的新領域。 最初的回答者說它不是很有效,所以你可能想要查看該頁面上的其他解決方案。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.