2013-04-11 45 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