mysql - LEFT JOIN 四个表产生不需要的结果

标签 mysql sql join

我做了一个小项目经理。我需要知道有多少打开的项目分配给特定用户组的用户。

我创建了四个表:

用户

╔════╦══════════╦══════════════╗
║ id ║ group_id ║ full_name    ║
╠════╬══════════╬══════════════╣
║  1 ║     4    ║ Jescie Head  ║
╠════╬══════════╬══════════════╣
║  2 ║     1    ║ Amity Mooney ║
╠════╬══════════╬══════════════╣
║  3 ║     1    ║ Ivy Yates    ║
╠════╬══════════╬══════════════╣
║  4 ║     1    ║ Bo Goff      ║
╚════╩══════════╩══════════════╝

项目

╔════╦══════╦════════╗
║ id ║ code ║ status ║
╠════╬══════╬════════╣
║  1 ║ P001 ║    0   ║
╠════╬══════╬════════╣
║  2 ║ P002 ║    1   ║
╚════╩══════╩════════╝

群组

╔════╦══════╦═════════╦════════╗
║ id ║ type ║ name    ║ status ║
╠════╬══════╬═════════╬════════╣
║  1 ║   0  ║ Group 1 ║    1   ║
╠════╬══════╬═════════╬════════╣
║  2 ║   2  ║ Group 2 ║    1   ║
╠════╬══════╬═════════╬════════╣
║  4 ║   1  ║ Group 4 ║    1   ║
╚════╩══════╩═════════╩════════╝

项目用户

╔═════════╦════════════╗
║ id_user ║ id_project ║
╠═════════╬════════════╣
║    5    ║      2     ║
╠═════════╬════════════╣
║    4    ║      2     ║
╠═════════╬════════════╣
║    3    ║      2     ║
╠═════════╬════════════╣
║    4    ║      1     ║
╚═════════╩════════════╝

我希望了解有多少事件项目分配给组 1(类型 0)的用户。我的查询有效,显示了正确的用户,但也计算了状态为 0 的项目:

SELECT u.id, 
       u.full_name, 
       u.type, 
       Count(pu.id_project) AS assigned_projects 
FROM   users AS u 
       LEFT JOIN project_user AS pu 
              ON u.id = pu.id_user 
       JOIN groups AS g 
         ON g.id = u.group_id 
            AND g.type = 0 
       LEFT JOIN projects AS p 
              ON pu.id_project = p.id 
                 AND p.status = 1 
GROUP  BY u.id 
ORDER  BY u.type, u.id ASC 

更新

当前结果:

╔════╦══════════════╦══════╦═══════════════════╗
║ id ║   full_name  ║ type ║ assigned_projects ║
╠════╬══════════════╬══════╬═══════════════════╣
║  2 ║ Amity Mooney ║   3  ║         0         ║
╠════╬══════════════╬══════╬═══════════════════╣
║  3 ║   Ivy Yates  ║   6  ║         1         ║
╠════╬══════════════╬══════╬═══════════════════╣
║  4 ║    Bo Goff   ║   1  ║         2         ║
╚════╩══════════════╩══════╩═══════════════════╝

想要的结果:原因项目 2 已关闭。

╔════╦══════════════╦══════╦═══════════════════╗
║ id ║   full_name  ║ type ║ assigned_projects ║
╠════╬══════════════╬══════╬═══════════════════╣
║  2 ║ Amity Mooney ║   3  ║         0         ║
╠════╬══════════════╬══════╬═══════════════════╣
║  3 ║   Ivy Yates  ║   6  ║         0         ║
╠════╬══════════════╬══════╬═══════════════════╣
║  4 ║    Bo Goff   ║   1  ║         1         ║
╚════╩══════════════╩══════╩═══════════════════╝

数据库 fiddle : DB Fiddle

最佳答案

我认为在连接“项目”表时不应该使用左连接。此外,您的按行分组应该是固定的。请尝试下面的查询。

SELECT u.id,u.full_name,u.type,Count(pu.id_project) AS assigned_projects 
FROM users AS u 
JOIN groups AS g ON g.id = u.group_id AND g.type = 0 
LEFT JOIN project_user AS pu ON u.id = pu.id_user 
JOIN projects AS p ON pu.id_project = p.id AND p.status = 1 
GROUP BY u.id,u.full_name,u.type
ORDER  BY u.type, u.id ASC 

编辑:如果您想查看所有用户,即使没有为该用户分配事件项目,您也需要使用下面的内容(使用 case-when 而不是 COUNT 的 SUM 并删除连接行中的状态检查):

SELECT u.id,u.full_name,u.type,SUM(CASE WHEN p.status = 1 then 1 else 0 end) AS assigned_projects 
FROM users AS u 
JOIN groups AS g ON g.id = u.group_id AND g.type = 0 
LEFT JOIN project_user AS pu ON u.id = pu.id_user 
JOIN projects AS p ON pu.id_project = p.id
GROUP BY u.id,u.full_name,u.type
ORDER  BY u.type, u.id ASC 

编辑2:这里是在MSSQL中准备的示例数据。您需要删除 mysql 的 # 符号。

create table #users (id int, groupid int, fullname varchar(50))
create table #groups (id int, [type] int, name varchar(50),[status] bit)
create table #projects (id int, code varchar(50), [status] bit)
create table #project_user (id_user int , id_project int)

insert into #users values (1,4,'Jescie'),(2,1,'Amity'),(3,1,'Ivy'),(4,1,'Jesse')
insert into #projects values (1,'p001',0),(2,'p002',1)
insert into #groups values (1,0,'G1',1),(2,2,'G2',1),(4,1,'G4',1)
insert into #project_user values (5,2),(4,2),(3,2),(4,1)

SELECT u.id,u.fullname,g.[type], SUM(CASE WHEN p.status = 1 then 1 else 0 end) AS assigned_projects 
FROM #users AS u 
JOIN #groups AS g ON g.id = u.groupid AND g.type = 0 
LEFT JOIN #project_user AS pu ON u.id = pu.id_user 
LEFT JOIN #projects AS p ON pu.id_project = p.id 
GROUP BY u.id,u.fullname,g.[type]
ORDER  BY g.[type], u.id ASC 

enter image description here

关于mysql - LEFT JOIN 四个表产生不需要的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54095225/

相关文章:

php - mysqli_fetch_object 不返回某些表中字符串中的重音符号

c# - 从包含特定 dd/mm 的数据表中选择行

mySQL JOIN 用法

mysql - 如何使索引良好的 MySQL 表有效地连接

mysql - 如何最大限度地减少这些子查询的使用并提高性能?

MySQL错误: You have an error in your SQL syntax check the manual that corresponds to your MySQL server version for the right syntax to use

mysql - 使用 Sum 聚合时需要 ID 列不区分

java - 多个数据库的 Hibernate 自动递增字段

sql - 为什么要从此查询中获取 9 行?

MySQL 复杂查询