我有一个非常复杂的查询(我认为无论如何!)写。它将包括很多连接。
这是一个想法:一个任务链接到一个项目,一个项目链接到一个上下文。用户可以创建任务,他们将拥有该任务。但是,用户可以创建团队并与该团队共享项目。因此,参与该团队的任何人都可以看到该项目及其任务。
我想查询1)属于当前用户当前上下文的任务列表。 2)用户可以看到通过团队链接到项目的结果。
我想显示任务标题及其所属的项目名称。
加入团队时,用户指定哪个上下文将包含该团队的项目。这个想法是因为上下文将项目分开了。
以下是涉及的表格。 Users_teams和projects_teams用作链接表,将用户加入团队,将项目加入团队。
users
-----------------
id
tasks
------------------
id | user_id | project_id | title
projects
------------------
id | name | user_id | context_id
teams
------------------
id | name | user_id
users_teams
------------------
id | user_id | team_id | context_id
projects_teams
------------------
id | project_id | team_id
我的第一个想法是创建2个单独的查询;一个用于获取用户拥有的任务列表,另一个用于获取用户链接到的任务列表。问题是,这样我无法正确地进行排序,无论如何我的查询都会产生奇怪的结果。我想也许有一种方法可以在一个查询中完成所有操作?
我的第一个查询就是:
SELECT * FROM tasks
JOIN projects on tasks.project_id = projects.id
WHERE tasks.user_id = 2 AND projects.context_id = 5
我猜第二个会涉及加入users_teams,projects_teams表。
答案 0 :(得分:2)
以下查询如何:
SELECT
z.*
FROM (
SELECT
t1.*
FROM
tasks as t1
JOIN projects as p1 ON t1.project_id = p1.id
WHERE
t1.user_id = $userId
AND p1.context_id = $contextId
UNION
SELECT
t2.*
FROM
user_teams as utm
JOIN teams as tm ON utm.team_id = tm.id
JOIN project_teams as ptm ON tm.id = ptm.team_id
JOIN projects as p2 ON ptm.project_id = p2.id
JOIN tasks as t2 ON p2.id = t2.project_id
WHERE
utm.user_id = $userId
AND p2.context_id = $contextId
) as z
ORDER BY 4 ASC
查询只是检索指定的单独数据所需的两个查询的并集。然后订购这个联盟。
查询包含变量$ userId和$ contextId。
ORDER BY 4 ASC语句按结果集中的第4列排序,在本例中为tasks表中的标题列。
答案 1 :(得分:0)
艰难的部分是加入任务。只需在ON子句中执行OR条件
INNER JOIN tasks t
ON p.id = t.projectid
or u.id = t.user_id
完整SQL子句
SELECT
p.name,
t.title
FROM
users u
INNER JOIN users_teams ut
on u.id = ut.user_id
INNER JOIN projects_teams pt
ON ut.team_id = pt.project_id
INNER JOIN project p
ON project_id = p.id
INNER JOIN tasks t
ON p.id = t.projectid
or u.id = t.user_id