2010-06-13 27 views
0

請轉儲第一幫我修改這個查詢,以獲得預期的效果 - 已解決

CREATE TABLE IF NOT EXISTS `all_tag_relations` (
    `id_tag_rel` int(10) NOT NULL AUTO_INCREMENT, 
    `id_tag` int(10) unsigned NOT NULL DEFAULT '0', 
    `id_tutor` int(10) DEFAULT NULL, 
    `id_wc` int(10) unsigned DEFAULT NULL, 
    PRIMARY KEY (`id_tag_rel`), 
    KEY `All_Tag_Relations_FKIndex1` (`id_tag`), 
    KEY `id_wc` (`id_wc`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=19 ; 


INSERT INTO `all_tag_relations` (`id_tag_rel`, `id_tag`, `id_tutor`, `id_wc`) VALUES 
(1, 1, 1, NULL), 
(2, 2, 1, NULL), 
(3, 6, 2, NULL), 
(4, 7, 2, NULL), 
(8, 3, 1, 1), 
(9, 4, 1, 1), 
(10, 5, 2, 2), 
(11, 4, 2, 2), 
(15, 8, 1, 3), 
(16, 9, 1, 3), 
(17, 10, 1, 4), 
(18, 4, 1, 4), 
(19, 1, 2, 5), 
(20, 4, 2, 5); 

CREATE TABLE IF NOT EXISTS `tags` (
    `id_tag` int(10) unsigned NOT NULL AUTO_INCREMENT, 
    `tag` varchar(255) DEFAULT NULL, 
    PRIMARY KEY (`id_tag`), 
    UNIQUE KEY `tag` (`tag`), 
    KEY `id_tag` (`id_tag`), 
    KEY `tag_2` (`tag`), 
    KEY `tag_3` (`tag`), 
    KEY `tag_4` (`tag`), 
    FULLTEXT KEY `tag_5` (`tag`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=11 ; 



INSERT INTO `tags` (`id_tag`, `tag`) VALUES 
(1, 'Sandeepan'), 
(2, 'Nath'), 
(3, 'first'), 
(4, 'class'), 
(5, 'new'), 
(6, 'Bob'), 
(7, 'Cratchit'), 
(8, 'more'), 
(9, 'fresh'), 
(10, 'second'); 

CREATE TABLE IF NOT EXISTS `webclasses` (
    `id_wc` int(10) NOT NULL AUTO_INCREMENT, 
    `id_author` int(10) NOT NULL, 
    `name` varchar(50) DEFAULT NULL, 
    PRIMARY KEY (`id_wc`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=5 ; 



INSERT INTO `webclasses` (`id_wc`, `id_author`, `name`) VALUES 
(1, 1, 'first class'), 
(2, 2, 'new class'), 
(3, 1, 'more fresh'), 
(4, 1, 'second class'), 
(5, 2, 'sandeepan class'); 

關於系統 這些數據 - 該系統由導師和課程。 - 表All_Tag_Relations中的數據存儲每個註冊導師以及由導師創建的每個課程的標籤關係。標籤關係用於搜索課程。

當前的數據轉儲對應於已經創建了類「新班」和「新班」的名爲「第一班」,「更新鮮」,「第二班」和導師「鮑勃克拉奇特」的導師「Sandeepan Nath」 Sandeepan課程「。

我想獲得一個搜索查詢,它對搜索關鍵字執行AND邏輯,並返回每個這樣的類,這些類中的搜索項目在類名或其導師名中出現。

爲了方便,下面是搜索條件的一個例子列表和期望的結果: -


Search term   result classes (check the id_wc in the results)** 

first class    1 

Sandeepan Nath class  1 

Sandeepan Nath   1,3 

Bob Cratchit    2 

Sandeepan Nath bob  none 

Sandeepan Class   1,4,5 

我迄今已達高達該查詢

-- Two keywords search 


SET @tag1 = 4, @tag2 = 1; -- Setting some user variables to see where the ids go. 

SELECT wc.id_wc, sum(DISTINCT (
wtagrels.id_tag = @tag1 
)) AS key_1_class_matches, 
sum(DISTINCT (
wtagrels.id_tag = @tag2 
)) AS key_2_class_matches, 
sum(DISTINCT (
ttagrels.id_tag = @tag1 
)) AS key_1_tutor_matches, 
sum(DISTINCT (
ttagrels.id_tag = @tag2 
)) AS key_2_tutor_matches, 
sum(DISTINCT (
ttagrels.id_tag = wtagrels.id_tag 
)) AS key_class_tutor_matches 

FROM WebClasses as wc 
join all_tag_relations AS wtagrels on wc.id_wc = wtagrels.id_wc 
join all_tag_relations as ttagrels on (wc.id_author = ttagrels.id_tutor) 

WHERE (
wtagrels.id_tag = @tag1 
OR wtagrels.id_tag = @tag2 
OR ttagrels.id_tag = @tag1 
OR ttagrels.id_tag = @tag2 
) 
GROUP BY wtagrels.id_wc 
LIMIT 0 , 20 

對於搜索1或3個術語,刪除/添加此查詢中的變量部分。列出我對key_1_class_matches,key_2_class_matches,key_1_tutor_matches(比如,類鍵),key_2_tutor_matches對各種情況(比如教師鍵)值的觀察。


Search term   expected result     Observation 
first class    1    for class 1, all class keys+all tutor keys =1 

Sandeepan Nath class  1    for class 1, one class key+ all tutor keys = 1 

Sandeepan Nath   1,3   both tutor keys =1 for these classes 

Bob Cratchit    2    both tutor keys = 1 

Sandeepan Nath bob  none   no complete tutor matches for any class 

我發現一個規律,對於任何情況下,它應該出現在結果的類(ES)有比賽(所有的類鍵和導師鍵)的數量最多。 例如搜索「第一類」,僅針對類別= 1,關鍵匹配總數= 4(1 + 1 + 1 + 1) 搜索「Sandeepan Nath」,類別1,3,4(Sandeepan Nath所有類別)教師鍵匹配。

但沒有模式尋找「Sandeepan Class」 - 1,4,5類應匹配。 現在,我如何根據該模式將條件放入查詢中,以便只返回那些類。

我是否需要在這裏使用全文搜索,因爲它給出了評分/等級值,表示比賽的強度?任何示例查詢都會有幫助。

請注意 - 我已經找到解決方案,用於顯示任何/所有搜索條件與類名匹配的類。 Mysql - Help me alter this search query to get desired results但是,如果所有搜索條件都在輔導員名稱中,則不起作用。所以,我正在修改查詢和試驗。

+2

我認爲聲明「以方便」,在中間有一個有點遲。對不起,但我不明白你想做什麼。 – MJB 2010-06-13 21:39:27

回答

0

我自己找到了解決方案。我很高興!!!

關鍵在於導師和班級的單獨標籤關係表。即兩個表叫tutors_tag_relations和webclasses_tag_relations代替all_tag_relations如下: -

CREATE TABLE IF NOT EXISTS `tutors_tag_relations` (
    `id_tag_rel` int(10) NOT NULL AUTO_INCREMENT, 
    `id_tag` int(10) unsigned NOT NULL DEFAULT '0', 
    `id_tutor` int(10) DEFAULT NULL, 
    PRIMARY KEY (`id_tag_rel`), 
    KEY `All_Tag_Relations_FKIndex1` (`id_tag`), 
    KEY `id_tag` (`id_tag`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=5 ; 


INSERT INTO `tutors_tag_relations` (`id_tag_rel`, `id_tag`, `id_tutor`) VALUES 
(1, 1, 1), 
(2, 2, 1), 
(3, 6, 2), 
(4, 7, 2); 


CREATE TABLE IF NOT EXISTS `webclasses_tag_relations` (
    `id_tag_rel` int(10) NOT NULL AUTO_INCREMENT, 
    `id_tag` int(10) unsigned NOT NULL DEFAULT '0', 
    `id_tutor` int(10) DEFAULT NULL, 
    `id_wc` int(10) DEFAULT NULL, 
    PRIMARY KEY (`id_tag_rel`), 
    KEY `webclasses_Tag_Relations_FKIndex1` (`id_tag`), 
    KEY `id_wc` (`id_wc`), 
    KEY `id_tag` (`id_tag`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=21 ; 

INSERT INTO `webclasses_tag_relations` (`id_tag_rel`, `id_tag`, `id_tutor`, `id_wc`) VALUES 
(1, 3, 1, 1), 
(2, 4, 1, 1), 
(3, 5, 2, 2), 
(4, 4, 2, 2), 
(15, 8, 1, 3), 
(16, 9, 1, 3), 
(17, 10, 1, 4), 
(18, 4, 1, 4), 
(19, 1, 2, 5), 
(20, 4, 2, 5); 

那麼這個查詢工作: -

SET @tag1 = 4, @tag2 = 1; -- Setting some user variables to see where the ids go. 

SELECT wc.id_wc, sum(DISTINCT (
wtagrels.id_tag = @tag1 or ttagrels.id_tag = @tag1 
)) AS key_1_matches, 
sum(DISTINCT (
wtagrels.id_tag = @tag2 or ttagrels.id_tag = @tag2 
)) AS key_2_matches 

FROM WebClasses as wc 
join webclasses_tag_relations AS wtagrels on wc.id_wc = wtagrels.id_wc 
join tutors_tag_relations as ttagrels on (wc.id_author = ttagrels.id_tutor) 

WHERE (
wtagrels.id_tag = @tag1 
OR wtagrels.id_tag = @tag2 
OR ttagrels.id_tag = @tag1 
OR ttagrels.id_tag = @tag2 
) 
GROUP BY wtagrels.id_wc 
having key_1_matches = 1 and key_2_matches=1 
LIMIT 0 , 20 
+0

恭喜!最重要的是讓事情變得簡單,即使這意味着你的數據庫中有一個額外的表。 – 2010-06-20 20:44:13

1

我認爲你的設計不太好,很難理解,因爲你在同一個表中混合了導師和標籤。這就是爲什麼要進行查詢以獲得您想要的結果更困難的原因。在與Search termresult classes你的例子是很難說,當你想通過標籤搜索(=字類名)或標籤(=導師的名字)

我建議使用下表:
(如果tags你只有在webclasses的名字的話,你可以在表LIKE搜索和刪除表tagsall_tag_relations

CREATE TABLE `tutors` (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
    `name` varchar(64) NOT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1; 
INSERT INTO `tutors` (`id`,`name`) VALUES (1,'Sandeepan Nath'), (2,'Bob Cratchit'); 

CREATE TABLE `webclasses` (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
    `id_tutor` int(10) unsigned NOT NULL, 
    `name` varchar(64) NOT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1; 
INSERT INTO `webclasses` (`id`, `id_tutor`, `name`) VALUES 
(1, 1, 'first class'),(2, 2, 'new class'),(3, 1, 'more fresh'), (4, 1, 'second class'),(5, 2, 'sandeepan class'); 

CREATE TABLE `tags` (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
    `tag` varchar(64) NOT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1; 
INSERT INTO `tags` (`id`, `tag`) VALUES 
(1, 'sandeepan'),(3, 'first'),(4, 'class'),(5, 'new'),(8, 'more'),(9, 'fresh'),(10, 'second'); 

CREATE TABLE `all_tag_relations` (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
    `id_tag` int(10) unsigned NOT NULL, 
    `id_wc` int(10) unsigned NOT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='Tags of classes'; 
INSERT INTO `all_tag_relations` (`id_tag`, `id_wc`) VALUES 
(3, 1),(4, 1),(5, 2),(4, 2),(8, 3),(9, 3),(10,4),(4, 4),(1, 5),(4, 5); 

通過標籤搜索:

SELECT wc.*, COUNT(*) as tag_count, rel.id_tag from webclasses wc 
LEFT JOIN all_tag_relations rel ON wc.id = rel.id_wc 
WHERE (rel.id_tag = 3 OR rel.id_tag=4) 
GROUP BY wc.id 
HAVING tag_count!=1; 

我把tag_count!=1,因爲如果你添加條件的導師,tag_count0當所有的標籤不在類名稱。否則,tag_count總是大於0

我會建議使用的規則運算部分匹配,例如,如果用戶輸入firs clas,查詢將

SELECT * FROM webclasses 
WHERE 1 
     AND name REGEXP '([[:<:]]firs.*)' 
     AND name REGEXP '([[:<:]]clas.*)' 

(我把WHERE 1因爲在你的應用程序,你可以把條件foreach循環與AND name ......,以後你通過拆分空格的文本。)

結果是1 - first class

要選擇導師表數據量太大,您可以從以下查詢創建視圖:

SELECT wc.*, tut.name AS `tutor_name` FROM webclasses wc 
LEFT JOIN tutors tut ON wc.id_tutor = tut.id; 

並在上一個查詢中添加一些額外的條件。


P.S.你爲什麼說Bob Cratchit結果類別應該只有2而不是2, 5?因爲5也是他的課。

+0

你是對的,設計不太好。標籤關係需要保持分開。 – 2010-06-20 18:27:33