简体   繁体   English

SQL查询基于具有多个联接的子查询返回是/否

[英]SQL Query to return Yes/No Based on a Subquery with Many-Many Join

I have a many-to-many relational schema with 3 tables: Users, Teams, and Teamuser. 我有一个包含3个表的多对多关系架构:Users,Team和Teamuser。

Since a user can be on many teams and a team can have many users, teamuser is a table that joins users.id to teams.id. 由于一个用户可以在多个团队中,一个团队可以有多个用户,因此teamuser是一个将users.id联接到team.id的表。

I'd like to do a query that asks "With a given user ID, show me all of the teams in the teams table, with a calculated field called "member" that returns 1 if the given user is a member of that team, and a 0 otherwise" 我想执行一个查询,询问“使用给定的用户ID,向我显示teams表中的所有团队,并计算一个称为“ member”的字段,如果给定的用户是该团队的成员,则返回1,否则为0”

Is there a way to do this with one query directly in MySQL? 有没有一种方法可以直接在MySQL中对一个查询执行此操作?

TeamUser: TeamUser:

id  teamid  userid
5   1 [->]  1 [->]
1   1 [->]  2 [->]
2   2 [->]  2 [->]
6   3 [->]  1 [->]

teamid is a foreign key joined to Teams.id. teamid是加入Teams.id的外键。 userid is a foreign key on Users.id userid是Users.id上的外键

Teams: 团队:

id  name
1   Whomping Willows
2   Chudley Cannons

Users: 用户:

id  username    
1   fred
2   finn    
3   paul    
16  pickles

Run something like the following to get the Cartesian product and then do the correlated sub-select wrapped in a coalesce to indicate membership? 运行如下所示的操作以获得笛卡尔积,然后将相关子选择包装在合并中以表示从属关系?

select u.username, t.teamname, COALESCE((select 1 from teamusers itu where itu.teamid = t.teamid and itu.userid = u.userid), 0) from users u, teams t where u.username = 'finn' 从用户u中选择u.username,t.teamname,COALESCE((从teamusers itu中选择1 itu其中itu.teamid = t.teamid和itu.userid = u.userid),0)从用户u中选择t,其中u.username ='finn “

Warning though this will not scale well as it does a select from team users for each row in the outer Cartesian product. 警告,尽管这样做不能很好地扩展,因为它会从团队用户中选择外部笛卡尔积的每一行。 More teams == more rows to run the sub-select 更多团队==更多行来运行子选择

Here how you can do it 在这里你怎么做

select
t.id,
t.name,
case when x.userid is not null then 1 else 0 end as `member`
from teams t
left join (
 select 
 tu.userid,
 tu.teamid
 from teamuser tu 
 left join users u on u.id = tu.userid  
 where u.id = 1 -- change the user id here which you are looking at
)x
on x.teamid = t.id

If i understand you correctly, you want to display result with two columns: first = Team , second - Member . 如果我正确理解您的意思,那么您想用两列显示结果:first = Team ,second- Member Result set will consist with all of the teams, and member column - is given username is a member of the team. 结果集将包含所有团队,并且成员列-给出的用户名是团队的成员。 Then, you can use following query: 然后,您可以使用以下查询:

SELECT a.name AS team_name,
      CASE WHEN c.username = 'fred' THEN 1 ELSE 0 END AS member 
  FROM Teams AS a JOIN TeamUser AS b ON a.id = b.teamid
                  JOIN Users AS c ON b.userid = c.id;

(Updated after actually testing on MySQL rather than Oracle.) (在MySQL而不是Oracle上进行实际测试后更新。)

You could work along 你可以一起工作

set @userID = 1;

SELECT
  TeamsOuter.name
  , CASE IFNULL((SELECT Users.id FROM Users JOIN TeamUser ON Users.id = TeamUser.userID JOIN Teams ON TeamUser.teamID = Teams.id WHERE Teams.id = TeamsOuter.id AND Users.id = @userID), 0) WHEN 0 THEN 0 ELSE 1 END member
  , IF((SELECT Users.id FROM Users JOIN TeamUser ON Users.id = TeamUser.userID JOIN Teams ON TeamUser.teamID = Teams.id WHERE Teams.id = TeamsOuter.id AND Users.id = @userID) IS NULL, 0, 1) memberToo
FROM Teams TeamsOuter
;

using either CASE or IF . 使用CASEIF
As the question is explicit on "With a given user ID […]", this is being used in the query. 由于该问题在“使用给定的用户ID […]”中是明确的,因此正在查询中使用它。

NB: When checking the results: "TeamUser" does reference a team with "teamID" 3, which does not exist… 注意:检查结果时:“ TeamUser”确实引用了一个“ teamID”为3的团队,该团队不存在……

If you wanted actually everything in one place: 如果您实际上希望将所有内容都放在一个位置:

SELECT
  UsersOuter.userName
  , TeamsOuter.name
  , IF((SELECT Users.id FROM Users JOIN TeamUser ON Users.id = TeamUser.userID JOIN Teams ON TeamUser.teamID = Teams.id WHERE Teams.id = TeamsOuter.id AND Users.id = UsersOuter.id) IS NULL, 0, 1) member
FROM Teams TeamsOuter, Users UsersOuter
ORDER BY UsersOuter.userName, TeamsOuter.name
;

SQL Fiddle SQL小提琴

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM