2014-04-24 71 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;