2011-11-04 31 views
5

我有這樣的場景:SQL WHERE用LIKE和比較的一個字段

我要檢查特定的詞,如果他們匹配的術語,我將不得不更新頁面的內容和鏈接到期限。但現在我正在專注於獲取內容的一部分與特定術語相同。

這是我需要做的一個想法,但它不工作,因爲子查詢返回多個字段。

我想找到WHERE m.module_content就像我有的任何術語,但它應該與他們一起檢查。

SELECT m.module_termid, t.term_name, m.module_name, m.module_content 
FROM modules m 
JOIN terms t ON m.module_termid = t.term_id 
WHERE m.module_content LIKE '%' || (SELECT term_name FROM terms) || '%' 

module_content在HTML格式的文本,所以最終所有我需要做的是,如果匹配的一個術語,它是沒有聯繫,我會添加一個鏈接到特定的術語。

什麼是最好的選擇在這裏做? (我使用MySQL的BTW)

爲了讓你的預期結果是什麼一個例子:

條款:ID:1,名稱:你好模塊:ID:1,內容:< p >的Hello World </p>

我想與ID 1模塊被提出來了,因爲它包含了一個地方有術語名爲 「你好」

更新的內容:

試圖Pablo的解決方案,但是,這是發生了什麼:

enter image description here

「雷·戴維斯」無關的「浮動」一詞例如,所以不應該出現。

+0

嘗試我的方法然後:) –

回答

5

我想你只需要改變你的JOIN條件是這樣的:

SELECT m.module_termid, t.term_name, m.module_name, m.module_content 
    FROM modules m 
    JOIN terms t ON (m.module_content LIKE '%' || t.term_name || '%') 

說了這麼多,這可能是潛在的非常低效的。考慮使用FULL TEXT INDEX INSTEAD進行此操作。

+0

我認爲這是一個笛卡爾積 –

+0

它不是一個完整的笛卡爾積。這是一個連接,條件是將生成NxM行......並且您的連接條件應該是您想要的:所有行中''terms'表中有'term'的所有​​行。 –

+0

你是對的,理想情況下,我就是這樣。看看上面提供的一個示例答案(請注意,Courtesy Double Up是該術語,並且

Ray Davis

是內容,除非術語名稱是Ray Davis,否則不應出現此內容:禮貌雙擊\t不明白浮動\t

Ray Davis

2

MySQL沒有任何連接運算符和查詢實際上應該寫成:

SELECT m.module_termid, t.term_name, m.module_name, m.module_content 
    FROM modules m 
    JOIN terms t ON m.module_content LIKE CONCAT('%', t.term_name, '%'); 

但是發生了什麼事:

m.module_content LIKE '%' || t.term_name || '%' 

實際上相當於

(m.module_content LIKE '%') || (t.term_name) || ('%') 

這總是1。因此,你有一個笛卡爾積=)

UPD:多爲自己是一個參考,MySQL的確實有一個連接符||,但使用它應該設置PIPES_AS_CONCAT模式:

mysql> SET sql_mode= 'pipes_as_concat'; 
Query OK, 0 rows affected (0.00 sec) 

mysql> SELECT 'qwe' || 'asd'; 
+----------------+ 
| 'qwe' || 'asd' | 
+----------------+ 
| qweasd   | 
+----------------+ 
1 row in set (0.00 sec) 
4

後一些研究,我的解決辦法是這樣的:

SELECT m.module_termid, t.term_name, m.module_name, m.module_content 
    FROM modules m 
    INNER JOIN terms t ON m.module_termid = t.term_id 
    WHERE m.module_content LIKE CONCAT('%', TRIM(t.term_name), '%') 

編輯:關於保羅摩根評論,我換成CONCAT('%', t.term_name, '%')CONCAT('%', TRIM(t.term_name), '%')小號o t.term_name中的所有空格都被刪除。如果您需要在t.term_name的空格,只是刪除TRIM呼叫,使用舊版本(CONCAT('%', t.term_name, '%')

+0

+1,但你需要在CONCAT中修剪t.term_name以獲得這個工作權。你不需要在t.term_name中有任何尾隨空格。 –

0

嘗試下面的查詢 -

SELECT 
    tp.module_termid, 
    tp.term_name, 
    tp.module_name, 
    tp.module_content 
FROM (
     SELECT 
      m.module_termid, 
      t.term_name, 
      m.module_name, 
      m.module_content, 
      IF(LOCATE(t.term_name,m.module_content)!=0, m.module_content, ' ') 
       as required_content 
     FROM modules m 
     LEFT JOIN terms t ON m.module_termid = t.term_id 
    ) tp 
WHERE tp.required_content != ''; 

對於上面的查詢,你會得到所有行term_name列數據作爲整個單詞出現在模塊表的module_content列中。如果你不想只匹配整個單詞,那麼你可以使用MYSQL的正則表達式函數代替LOCATE函數。

LOCATE功能的文檔可以發現here

1

你可以試試這個:

SELECT m.module_termid, t.term_name, m.module_name, m.module_content 
    FROM modules m 
    JOIN terms t ON (m.module_content LIKE '%' + t.term_name + '%') 
1

而不是「喜歡」,用「IN」應該是解決方案:像: -

SELECT m.module_termid,t.term_name,m.module_name,m.module_content
FROM modules m JOIN terms t ON m.module_termid = t.term_id
WHERE m.module_content IN(SELECT term_name FROM terms);

0

我不認爲這是解決這樣你有很多的模塊項目this.supports問題的好辦法,而流行的詞是limit.each時候你Exec的SQL,它需要大量的的磁盤io並可能阻止在線mysql數據庫。 我的方法是這樣的:

  1. 顛倒索引模塊內容。
  2. 用索引搜索熱門詞彙。
  3. 將模塊ID綁定到關鍵字。

正如你所看到的,它是非常有效和快速的。所以,問題是如何在模塊內容上做倒排索引。 sphinx會做得很好。 希望這會幫助你:)