2013-04-11 42 views
0

我是新來的高級MySQL查詢,所以請您在這裏不錯...MySQL查詢 - 多表 - 排序關聯 - 刪除重複

讓我們假設我有以下表...

Table Name: users 

username other_non_relevant_field 
======== ======================== 
Bob  blah blah blah 
Steve  blah blah blah 
Adam  blah blah blah 



Table Name: table_1 

username field_abc field_def other_non_relevant_field 
======== ========= ========= ======================== 
Steve  quick  brown  blah blah blah 
Adam  fox   quick  blah blah blah 



Table Name: table_2 

username field_ghi field_jkl other_non_relevant_field 
======== ========= ========= ======================== 
Bob   fox   fox   blah blah blah 
Bob   brown  quick  blah blah blah 
Steve  fox   lazy   blah blah blah 
Adam  jump   dog   blah blah blah 

因此,讓我們假設我想返回所有包含單詞「quick」或「brown」的用戶的列表,而不管他們在哪個表或字段中,並根據相關性顯示結果。要做到這一點,我用這個查詢:

SELECT users.username, table_1.field_abc, table_1.field_def, 
    table_2.field_ghi, table_2.field_jkl 
FROM users 
JOIN table_1 ON (table_1.username=users.username) 
JOIN table_2 ON (table_2.username=users.username) 
WHERE 
    table_1.field_abc LIKE "%quick%" OR table_1.field_abc LIKE "%brown%" 
    OR 
    table_1.field_def LIKE "%quick%" OR table_1.field_def LIKE "%brown%" 
    OR 
    table_2.field_ghi LIKE "%quick%" OR table_2.field_ghi LIKE "%brown%" 
    OR 
    table_2.field_jkl LIKE "%quick%" OR table_2.field_jkl LIKE "%brown%" 
ORDER BY (
    (
     CASE WHEN table_1.field_abc LIKE "%quick%" 
     THEN 1 
     ELSE 0 
     END 
    ) + (
     CASE WHEN table_1.field_abc LIKE "%brown%" 
     THEN 1 
     ELSE 0 
     END 
    ) + (
     CASE WHEN table_1.field_def LIKE "%quick%" 
     THEN 1 
     ELSE 0 
     END 
    ) + (
     CASE WHEN table_1.field_def LIKE "%brown%" 
     THEN 1 
     ELSE 0 
     END 
    ) + (
     CASE WHEN table_2.field_ghi LIKE "%quick%" 
     THEN 1 
     ELSE 0 
     END 
    ) + (
     CASE WHEN table_2.field_ghi LIKE "%brown%" 
     THEN 1 
     ELSE 0 
     END 
    ) + (
     CASE WHEN table_2.field_jkl LIKE "%quick%" 
     THEN 1 
     ELSE 0 
     END 
    ) + (
     CASE WHEN table_2.field_jkl LIKE "%brown%" 
     THEN 1 
     ELSE 0 
     END 
    ) 
) DESC; 

我現在有幾個問題...

1)查詢似乎很長。有沒有更簡單的方法來做到這一點?

2)如何使LIKE不區分大小寫,這樣%qUiCk%仍會返回結果?

3)目前每個相關記錄都被返回;但是,我實際上只希望每個用戶得到一個結果,但首先列出的是最高的相關用戶。我怎麼做?

+0

回覆:問題#2 ... 是搜索情況下,在默認情況下不區分大小寫? – 2013-04-11 16:13:24

+0

是的,他們通常在MySQL中。請參閱下面的答案。 – 2013-04-11 16:54:25

回答

1

要回答的問題1),你可以,如果真有

REGEXP '(a|b)' 

二,更換

LIKE '%a%' OR LIKE '%b%' 

a REGEXP b返回1或0,如果假的,所以你可以在去除CASE小號ORDER BY。試試這個:

SELECT users.username, table_1.field_abc, table_1.field_def, 
    table_2.field_ghi, table_2.field_jkl 
FROM users 
JOIN table_1 ON table_1.username = users.username 
JOIN table_2 ON table_2.username = users.username 
WHERE 
    table_1.field_abc REGEXP "(quick|brown)" OR 
    table_1.field_def REGEXP "(quick|brown)" OR 
    table_2.field_ghi REGEXP "(quick|brown)" OR 
    table_2.field_jkl REGEXP "(quick|brown)" 
ORDER BY (
    (table_1.field_abc REGEXP "(quick|brown)") + 
    (table_1.field_def REGEXP "(quick|brown)") + 
    (table_2.field_ghi REGEXP "(quick|brown)") + 
    (table_2.field_jkl REGEXP "(quick|brown)") 
) DESC; 

回答問題2)。 LIKEREGEXP甚至=在MySQL中默認情況下不區分大小寫,對於CHAR,VARCHARTEXT字段。要執行區分大小寫的搜索,您需要:

  1. 添加BINARY關鍵字。例如:REGEXP BINARY '(a|b)'

  2. 更改字段類型BINARYVARBINARY,或BLOB

  3. 變化領域的文字覈對你正在尋找一個區分大小寫的。

要回答的問題3),你就需要添加一個GROUP BY條款,是這樣的:

SELECT users.username, SUM(
    (table_1.field_abc REGEXP "(quick|brown)") + 
    (table_1.field_def REGEXP "(quick|brown)") + 
    (table_2.field_ghi REGEXP "(quick|brown)") + 
    (table_2.field_jkl REGEXP "(quick|brown)") 
) hits, 
    table_1.field_abc, table_1.field_def, 
    table_2.field_ghi, table_2.field_jkl 
FROM users 
JOIN table_1 ON table_1.username = users.username 
JOIN table_2 ON table_2.username = users.username 
WHERE 
    table_1.field_abc REGEXP "(quick|brown)" OR 
    table_1.field_def REGEXP "(quick|brown)" OR 
    table_2.field_ghi REGEXP "(quick|brown)" OR 
    table_2.field_jkl REGEXP "(quick|brown)" 
GROUP BY 
    users.username 
ORDER BY (
    (table_1.field_abc REGEXP "(quick|brown)") + 
    (table_1.field_def REGEXP "(quick|brown)") + 
    (table_2.field_ghi REGEXP "(quick|brown)") + 
    (table_2.field_jkl REGEXP "(quick|brown)") 
) DESC; 
+0

我想我會回答你對問題3的回答。然而,我不確定'SUM()'末尾的'hits'是什麼。它與'SUM()'有關嗎? – 2013-04-11 17:06:41

+0

我錯過了什麼?看看http://sqlfiddle.com/#!2/9c273/1,我將代碼放在那裏。 [sqlFiddle鏈接](http://sqlfiddle.com/#!2/9c273/1) – 2013-04-11 17:42:13

+0

對不起,'REGEXP's需要括號。請參閱http://sqlfiddle.com/#!2/9c273/21/0 – 2013-04-11 18:20:41