2010-05-28 89 views
1

請先執行下面的查詢來設置,這樣就可以幫助我: -MySQL查詢幫助 - 改變這個MySQL查詢得到這些結果?

CREATE TABLE IF NOT EXISTS `Tutor_Details` (
`id_tutor` int(10) NOT NULL auto_increment, 
`firstname` varchar(100) NOT NULL default '', 
`surname` varchar(155) NOT NULL default '', 
PRIMARY KEY (`id_tutor`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=41 ; 

INSERT INTO `Tutor_Details` (`id_tutor`,`firstname`, `surname`) VALUES 
(1, 'Sandeepan', 'Nath'), 
(2, 'Bob', 'Cratchit'); 

CREATE TABLE IF NOT EXISTS `Classes` (
`id_class` int(10) unsigned NOT NULL auto_increment, 
`id_tutor` int(10) unsigned NOT NULL default '0', 
`class_name` varchar(255) default NULL, 
PRIMARY KEY (`id_class`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=229 ; 

INSERT INTO `Classes` (`id_class`,`class_name`, `id_tutor`) VALUES 
(1, 'My Class', 1), 
(2, 'Sandeepan Class', 2); 

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`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=18 ; 

INSERT INTO `Tags` (`id_tag`, `tag`) VALUES 
(1, 'Bob'), 
(6, 'Class'), 
(2, 'Cratchit'), 
(4, 'Nath'), 
(3, 'Sandeepan'), 
(5, 'My'); 

CREATE TABLE IF NOT EXISTS `Tutors_Tag_Relations` (
`id_tag` int(10) unsigned NOT NULL default '0', 
`id_tutor` int(10) default NULL, 
KEY `Tutors_Tag_Relations` (`id_tag`), 
KEY `id_tutor` (`id_tutor`), 
KEY `id_tag` (`id_tag`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1; 

INSERT INTO `Tutors_Tag_Relations` (`id_tag`, `id_tutor`) VALUES 
(3, 1), 
(4, 1), 
(1, 2), 
(2, 2); 

CREATE TABLE IF NOT EXISTS `Class_Tag_Relations` (
`id_tag` int(10) unsigned NOT NULL default '0', 
`id_class` int(10) default NULL, 
`id_tutor` int(10) NOT NULL, 
KEY `Class_Tag_Relations` (`id_tag`), 
KEY `id_class` (`id_class`), 
KEY `id_tag` (`id_tag`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1; 

INSERT INTO `Class_Tag_Relations` (`id_tag`, `id_class`, `id_tutor`) VALUES 
(5, 1, 1), 
(6, 1, 1), 
(3, 2, 2), 
(6, 2, 2); 
  • 在本系統中的數據,我給了,名爲「Sandeepan納特」導師有已創建的類名爲「我的班」和導師名爲‘鮑伯’已創建名爲類‘Sandeepan類’。

要求 -

要對結果有限制執行一個查詢來顯示搜索結果按照與邏輯上是這樣的搜索關鍵字: -

  1. 如果「Sandeepan班」是(因爲「Sandeepan」是Sandeepan Nath的名字,Class在Sandeepan的班級名稱中存在)
  2. 如果搜索到「Class」這兩個Tutor_details表中的導師都將被返回(因爲「Sandeepan」是Sandeepan Nath的名字)被提取因爲Class是以兩個導師創建的班級的名字出現的。

以下是我迄今爲止所取得(PHP MySQL的): -

<?php 
$searchTerm1 = "Sandeepan"; 
$searchTerm2 = "Class"; 

mysql_select_db("test"); 


$sql = "SELECT td.* 
FROM Tutor_Details AS td 
LEFT JOIN Tutors_Tag_Relations AS ttagrels ON td.id_tutor = ttagrels.id_tutor 
LEFT JOIN Classes AS wc ON td.id_tutor = wc.id_tutor 
LEFT JOIN Class_Tag_Relations AS wtagrels ON td.id_tutor = wtagrels.id_tutor 

LEFT JOIN Tags as t1 on ((t1.id_tag = ttagrels.id_tag) OR (t1.id_tag = wtagrels.id_tag)) 
LEFT JOIN Tags as t2 on ((t2.id_tag = ttagrels.id_tag) OR (t2.id_tag = wtagrels.id_tag)) 


where t1.tag LIKE '%".$searchTerm1."%' 
AND t2.tag LIKE '%".$searchTerm2."%' 

GROUP BY td.id_tutor 
LIMIT 10 
"; 

$result = mysql_query($sql); 
echo $sql; 
if($result) 
{ 

while($rec = mysql_fetch_object($result)) $recs[] = $rec; 
//$rec = mysql_fetch_object($result); 
echo "<br><br>"; 

if(is_array($recs)) 
{ 
foreach($recs as $each) 
{ 
print_r($each); 
echo "<br>"; 
} 

} 

} 
?> 

但結果是: -

如果 「Sandeepan納特」 進行搜索,它不返回任何如果搜索到「Sandeepan Class」,則返回Sandeepan的行(而不是兩個導師) 如果搜索到「Bob Class」,它會正確返回Bob的行 如果搜索到「Bob Cratchit」它不會返回任何導師(而不是onl Ÿ

回答

1

問題是,你有2個搜索詞和你不是產生在其中您可以搜索來自同一個關係表中的兩個標籤(這是很容易看到,如果你看一下從您查詢的結果沒有任何行限制他們td,*)。解決辦法,如果你想這樣做的SQL,是產生用於每位教師/類的關係(同樣,這種解釋讓很多更有意義,當你看完整的查詢結果)標籤的所有2搜索詞的排列。無論如何,這裏是我採取修復SQL的方式,你這樣做:

SELECT td.* 
FROM Tutors_Tag_Relations AS ttagrels1 
JOIN Tutors_Tag_Relations AS ttagrels2 ON 
    ttagrels2.id_tutor = ttagrels1.id_tutor AND 
    ttagrels2.id_tag != ttagrels1.id_tag 
JOIN Class_Tag_Relations AS wtagrels1 ON 
    wtagrels1.id_tutor = ttagrels1.id_tutor AND 
    wtagrels1.id_tag != ttagrels1.id_tag AND 
    wtagrels1.id_tag != ttagrels2.id_tag 
JOIN Class_Tag_Relations AS wtagrels2 ON 
    wtagrels2.id_tutor = ttagrels1.id_tutor AND 
    wtagrels2.id_tag != wtagrels1.id_tag AND 
    wtagrels2.id_tag != ttagrels1.id_tag AND 
    wtagrels2.id_tag != ttagrels2.id_tag 
JOIN Tags as t1 ON 
    t1.id_tag = ttagrels1.id_tag OR 
    t1.id_tag = ttagrels2.id_tag OR 
    t1.id_tag = wtagrels1.id_tag OR 
    t1.id_tag = wtagrels2.id_tag 
JOIN Tags as t2 ON 
    t2.id_tag != t1.id_tag AND 
    (t2.id_tag = ttagrels1.id_tag OR 
    t2.id_tag = ttagrels2.id_tag OR 
    t2.id_tag = wtagrels1.id_tag OR 
    t2.id_tag = wtagrels2.id_tag) 
LEFT JOIN Tutor_Details as td ON ttagrels1.id_tutor = td.id_tutor 
LEFT JOIN Classes AS wc ON td.id_tutor = wc.id_tutor 
WHERE 
    t1.tag LIKE '%Sandeepan%' AND 
    t2.tag LIKE '%Nath%' 
GROUP BY td.id_tutor 

這真的不是我如何去了解它。事情會變得非常,非常沉重試圖做這種通過加入搜索的,如果你添加更多的搜索條件只會變得更糟。

缺失排列的說明:

這些表通過去除where子句,該組子句,刪除重複且僅示出了TD1和TD2的列產生的。

你的道:

+--------+-----------+--------+-----------+ 
| id_tag | tag  | id_tag | tag  | 
+--------+-----------+--------+-----------+ 
|  1 | Bob  |  3 | Sandeepan | 
|  1 | Bob  |  6 | Class  | 
|  2 | Cratchit |  3 | Sandeepan | 
|  2 | Cratchit |  6 | Class  | 
|  3 | Sandeepan |  1 | Bob  | 
|  3 | Sandeepan |  2 | Cratchit | 
|  3 | Sandeepan |  5 | My  | 
|  3 | Sandeepan |  6 | Class  | 
|  4 | Nath  |  5 | My  | 
|  4 | Nath  |  6 | Class  | 
|  5 | My  |  3 | Sandeepan | 
|  5 | My  |  4 | Nath  | 
|  6 | Class  |  1 | Bob  | 
|  6 | Class  |  2 | Cratchit | 
|  6 | Class  |  3 | Sandeepan | 
|  6 | Class  |  4 | Nath  | 
+--------+-----------+--------+-----------+ 

現在,如果我們看看這個我們看到td1.id_tag從目前無論是類或導師的關係產生的。此外td2.id_Tag是由班級或導師關係出示的。然而,對於任何1行這一結果td1.id_Tag和td2.id_tag不能來自同一關係表。它們始終是Class/Tutors或Tutors/Class,對於Class/Class或Tutors/Tutors標籤而言,永遠不會有行(請記住Class關係表中存在Sandeepan標籤)。這意味着你無法搜索「Sandeepan」,「Nash」或「Bob」「Cratchit」,因爲在這兩種情況下,這些標籤只出現在一張表中。

我的方式:

+--------+-----------+--------+-----------+ 
| id_tag | tag  | id_tag | tag  | 
+--------+-----------+--------+-----------+ 
|  1 | Bob  |  2 | Cratchit | 
|  1 | Bob  |  3 | Sandeepan | 
|  1 | Bob  |  6 | Class  | 
|  2 | Cratchit |  1 | Bob  | 
|  2 | Cratchit |  3 | Sandeepan | 
|  2 | Cratchit |  6 | Class  | 
|  3 | Sandeepan |  1 | Bob  | 
|  3 | Sandeepan |  2 | Cratchit | 
|  3 | Sandeepan |  4 | Nath  | 
|  3 | Sandeepan |  5 | My  | 
|  3 | Sandeepan |  6 | Class  | 
|  4 | Nath  |  3 | Sandeepan | 
|  4 | Nath  |  5 | My  | 
|  4 | Nath  |  6 | Class  | 
|  5 | My  |  3 | Sandeepan | 
|  5 | My  |  4 | Nath  | 
|  5 | My  |  6 | Class  | 
|  6 | Class  |  1 | Bob  | 
|  6 | Class  |  2 | Cratchit | 
|  6 | Class  |  3 | Sandeepan | 
|  6 | Class  |  4 | Nath  | 
|  6 | Class  |  5 | My  | 
+--------+-----------+--------+-----------+ 

我所有的SQL確實是產生缺失的類/班主任/導師行,其修復該問題。

+0

嗨邁克感謝您的解決方案。它的工作原理非常完美,我完全同意「試圖通過連接進行這種搜索將會變得非常非常沉重」。 但是我並沒有完全明白你的意思,說「解決方案,如果你想用SQL來做,就是生成用於每個導師/類關係的標籤的所有2個搜索項排列」。 如果你至少可以給我更多的線索,讓我得到更清晰的圖片,那會很棒。再次感謝您的幫助 – 2010-05-28 09:49:12

+0

嗨邁克,這個查詢會變得非常沉重,就像我們所看到的一樣。請檢查我的問題http://stackoverflow.com/questions/2927142/mysql-help-me-alter-this-query-to-apply-and-logic-instead-of-or-in-searching其中用戶已經給更好的解決方案。請看看你是否可以進一步幫助我,謝謝 – 2010-06-02 20:20:46

+0

嗨邁克,我改進了一點我的搜索邏輯。爲了減少連接的複雜性和數量,我現在在搜索執行期間創建一個名爲All_Tag_Relations的臨時表,其中包含來自Tutors_Tag_Relations和Webclasses_Tag_Relations(現在忽略Learning_Packs_Tag_Relations)的所有數據。但是,仍然有一個問題,請檢查我的新問題,如果你可以幫助http://stackoverflow.com/questions/3030022/mysql-help-me-alter-this-search-query-to-get-desired-結果 – 2010-06-12 21:58:30