2014-04-24 98 views
0

我想在表「項目」上的搜索請求建立一個SQL查詢。 搜索也與其他與項目表有關係的表有關。SQL多重連接與空結果

我想:

SELECT projects.* 

FROM projects 
    LEFT JOIN documents   ON documents.projectID  = projects.id 
    LEFT JOIN subdocuments  ON documents.id   = subdocuments.documentID 
    LEFT JOIN subdocuments_tags ON subdocuments.id   = subdocuments_tags.subdocumentID 
    JOIN tags     ON subdocuments_tags.tagID = tags.id 

WHERE (projects.name LIKE "%Test%" 
    OR projects.clientName LIKE "%Test%" 
    OR projects.description LIKE "%Test%" 
    OR projects.defaultTags LIKE "%Test%" 
    OR documents.name LIKE "%Test%" 
    OR subdocuments.name LIKE "%Test%" 
    OR documents.description LIKE "%Test%" 
    OR subdocuments.description LIKE "%Test%" 
    OR tags.name LIKE "%Test%") 
AND (projects.hidden = 0 
    OR projects.ownerID = 2 
    OR projects_users.userID = 2) 

GROUP BY projects.id 

ORDER BY projects.updateTime DESC; 

的問題是,如果項目沒有任何證件,結果總是空的,即使沒有一個WHERE子句。

+1

J OIN標記ON正在創建問題,請嘗試將它作爲左連接 –

+0

有一個「內連接」,可能是問題,如果可以,則將其設置爲「左連接」。 –

+0

謝謝-_-它的工作原理 – user1423647

回答

1

@MatBailie

進一步討論...

DROP TABLE IF EXISTS i; 

DROP TABLE IF EXISTS table_a; 

CREATE TABLE ints (i INT NOT NULL PRIMARY KEY); 

INSERT INTO ints VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); 

CREATE TABLE table_a (i INT NOT NULL,x CHAR(1) NOT NULL, PRIMARY KEY (i,x)); 

INSERT INTO table_a VALUES 
(1,'a'), 
(1,'b'), 
(1,'c'), 
(1,'d'), 
(1,'e'), 
(2,'a'), 
(2,'b'), 
(2,'c'), 
(3,'a'), 
(3,'b'), 
(4,'a'); 

SELECT * FROM ints; 
+---+ 
| i | 
+---+ 
| 0 | 
| 1 | 
| 2 | 
| 3 | 
| 4 | 
| 5 | 
| 6 | 
| 7 | 
| 8 | 
| 9 | 
+---+ 

SELECT * FROM table_a; 
+---+---+ 
| i | x | 
+---+---+ 
| 1 | a | 
| 1 | b | 
| 1 | c | 
| 1 | d | 
| 1 | e | 
| 2 | a | 
| 2 | b | 
| 2 | c | 
| 3 | a | 
| 3 | b | 
| 4 | a | 
+---+---+ 

SELECT m.* FROM ints m LEFT JOIN table_a n ON n.i = m.i WHERE n.x IN('c','d'); 
+---+ 
| i | 
+---+ 
| 1 | 
| 1 | 
| 2 | 
+---+ 

SELECT m.* FROM ints m JOIN table_a n ON n.i = m.i WHERE n.x IN('c','d'); 
+---+ 
| i | 
+---+ 
| 1 | 
| 1 | 
| 2 | 
+---+ 

http://www.sqlfiddle.com/#!2/90c6ed/1

+0

http://www.sqlfiddle.com/#!2/f51875/4 – MatBailie

+0

我看到(有點) - 我不認爲我以前見過這種實現!很好的例子BTW。但它看起來像一個黑客,因爲它依賴於「project.name = ... OR ...」構造。還有另一種寫作方式嗎? – Strawberry

+0

我不會稱之爲黑客。唯一我認爲*不尋常的是'GROUP BY id'而不是'DISTINCT'或'GROUP BY id,name'。替代方案可以是'WHERE name LIKE'%test%'或EXISTS()',但在OP的情況下,由於有4個相關的表, *(第一個相關查詢僅引用第一個表,第二個相關查詢需要連接兩個表,第三個相關查詢需要連接三個表等)*。我實際上認爲OP的做法是正確的*(一旦'JOIN'變成'LEFT JOIN')*。 – MatBailie

0

正如上面提到的評論使用LEFT JOIN,包括從項目表,即使沒有行在文檔,子文檔或標籤表中匹配行

SELECT projects.* 
FROM projects 
LEFT JOIN documents ON documents.projectID = projects.id 
LEFT JOIN subdocuments ON documents.id = subdocuments.documentID 
LEFT JOIN subdocuments_tags ON subdocuments.id = subdocuments_tags.subdocumentID 
LEFT JOIN tags ON subdocuments_tags.tagID = tags.id 
WHERE (projects.name LIKE "%Test%" OR projects.clientName LIKE "%Test%" OR projects.description LIKE "%Test%" OR projects.defaultTags LIKE "%Test%" OR documents.name LIKE "%Test%" OR subdocuments.name LIKE "%Test%" OR documents.description LIKE "%Test%" OR subdocuments.description LIKE "%Test%" OR tags.name LIKE "%Test%") 
    AND (projects.hidden = 0 OR projects.ownerID = 2 OR projects_users.userID = 2) 
GROUP BY projects.id 
ORDER BY projects.updateTime DESC;