簡體   English   中英

具有多個字段的多個關鍵字的Php MySql查詢

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM