2017-03-07 30 views
0

我有一段簡單的代碼,用於從我的數據庫表中的所有行中搜索三列。表名是「articles」,我要搜索的3列是「Title,Description和Tags」。目前,我搜索一個單詞或詞組,並向我顯示結果,我想知道的是,如果有方法可以顯示結果找到3列中的哪一列。我是否必須對每一行返回一個單獨的查詢作爲結果,還是有更簡單的方法?我在下面包含了我的代碼片段。顯示在搜索查詢中找到了哪一列

$query = $_GET['q']; 
$sql = "SELECT * FROM articles WHERE (`title` LIKE '%".$query."%') OR (`description` LIKE '%".$query."%') OR (`tags` LIKE '%".$query."%') ORDER BY dateadded"; 
$query = $db->query($sql); 
while($row = $query->fetch_assoc()) { 
display 
} 
+3

一個稱爲標籤欄的存在通常是對症的設計不良。 – Strawberry

+1

您可以使用UNION來解決您的問題 – Strawberry

+0

是的我知道列名稱並不完美。我將它們重命名爲使事情變得簡單,以便更容易地提出我的問題。 – Born2DoubleUp

回答

1

速戰速決是使用條件來選擇一些附加列:

SELECT *, 
    IF(`title` LIKE '%".$query."%',  1, 0) AS conditionTitle, 
    IF(`description` LIKE '%".$query."%', 1, 0) AS conditionDescription, 
    IF(`tags` LIKE '%".$query."%',  1, 0) AS conditionTags 
FROM articles 
WHERE (`title` LIKE '%".$query."%') 
    OR (`description` LIKE '%".$query."%') 
    OR (`tags` LIKE '%".$query."%') 
ORDER BY dateadded"; 

現在,您可以檢查這些附加列的值每行中,以檢查是否$query中被發現特定領域。

請注意,您應該使用準備好的語句,因爲您現在可能有sql注入問題。

+0

我得再研究一下你的代碼,因爲我不確定它在做什麼。大聲笑我仍然是綠色的,當涉及到PHP和MySQL,試圖教自己所有這些東西一天一次,但這是建議,我一定會考慮它! – Born2DoubleUp

+0

@ Born2DoubleUp你會在每一行找到3個額外的列,你會發現這些列的值是'yep'或'nope'(1和0當然會移動方便......)。運行它,例如phpMyAdmin來查看結果。 – jeroen

+0

@ Born2DoubleUp我已經切換到整數輸出,使檢查更容易。 – jeroen

0

一種替代方法是在SELECT列表的表達式中測試條件。

我認爲最簡單的解釋方法就是舉例。但是我不能良心發表容易受SQL注入影響的示例代碼。

目前查詢:

SELECT a.* 
    FROM articles 
    WHERE a.`title`  LIKE CONCAT('%', ? ,'%') 
    OR a.`description` LIKE CONCAT('%', ? ,'%') 
    OR a.`tags`  LIKE CONCAT('%', ? ,'%') 
    ORDER 
    BY a.dateadded 

當前查詢,我們可以添加表情到SELECT列表。舉例:

SELECT IF(a.`title`  LIKE CONCAT('%', ? ,'%') ,1,0) AS match_in_title 
     , IF(a.`description` LIKE CONCAT('%', ? ,'%') ,1,0) AS match_in_description 
     , IF(a.`tags`  LIKE CONCAT('%', ? ,'%') ,1,0) AS match_in_tags 
     , a.* 
    FROM articles 
    WHERE a.`title`  LIKE CONCAT('%', ? ,'%') 
    OR a.`description` LIKE CONCAT('%', ? ,'%') 
    OR a.`tags`  LIKE CONCAT('%', ? ,'%') 
    ORDER 
    BY a.dateadded 

對於返回的每一行,都會計算SELECT列表中的表達式。條件測試(LIKE比較)評估爲TRUE,FALSE或NULL。 MySQL IF函數會將第一個參數評估爲布爾值,如果是,則返回第二個參數,elise返回第三個參數。

在此示例中,如果匹配,則表達式返回1。否則,它將返回0。還有很多其他選擇我們可以返回的值。我們還可以在單​​個表達式中組合條件,以返回單個值。

還有很多可能的表達式可以包含條件測試。我剛剛使用了MySQL IF函數。更符合ANSI標準的表達式可以使用CASE,例如,

SELECT CASE WHEN a.`title`  LIKE CONCAT('%', ? ,'%') 
      THEN 1 
      ELSE 0 
     END AS match_in_title 
0

像這樣的東西應該工作。 與傳遞的名爲search_articles和UNION ALL的表一起使用,將SELECT查詢組合在一起。

SELECT 
    search_column 
, * 
FROM (
    SELECT 
    'title' AS search_column 
    , * 
    FROM 
    artices 
    WHERE 
    title LIKE '%query%' 

    UNION ALL 

    SELECT 
    'description' AS search_column 
    , * 
    FROM 
    artices 
    WHERE 
    description LIKE '%query%' 

    UNION ALL 

    SELECT 
    'tags' AS search_column 
    , * 
    FROM 
    artices 
    WHERE 
    tags LIKE '%query%' 
) 
AS 
    search_articles 
+0

請注意,此查詢有可能多次從'articles'中返回相同的行。例如,如果「標籤」和「標題」上的行「匹配」。 – spencer7593

+0

@ spencer7593 true然後主題首發應該刪除關鍵字ALL後所有UNIONS刪除重複 –

+0

使用'UNION'來代替'UNION ALL'並沒有真正解決這個問題,因爲'search_column'返回的值將不同於查詢,「標題」與「標籤」。獨特的排序操作將保留兩行。 – spencer7593