加入另一个表后出现意外结果

时间:2011-09-23 16:13:28

标签: sql join

我使用三个表来获得最终结果。它们被称为project_board_membersusersproject_team

这是查询:

SELECT `project_board_members`.`member_id`,
       `users`.`name`,
       `users`.`surname`,
       `users`.`country`,
       `project_team`.`tasks_completed`
FROM `project_board_members`
JOIN `users`
    ON (`users`.`id` = `project_board_members`.`member_id`)
JOIN `project_team`
    ON (`project_team`.`user_id` = `project_board_members`.`member_id`)
WHERE `project_board_members`.`project_id` = '5'

你可以忽略最后一行,因为它只指向我正在使用的项目。

project_board_members包含三个条目,结构如下:

  • id
  • member_id
  • project_id
  • created_at;

我需要从该表中获取member_id。然后我加入users表格,获取namesurnamecountry。没问题。一切都有效! :)

之后,我需要为每个用户获取tasks_completed。它存储在project_team表中。最令人意想不到的是,我收到了四个条目,而project_board_members表格中只有三个条目的重要内容是什么。

为什么会这样?谢谢你的建议!

3 个答案:

答案 0 :(得分:1)

SQL连接创建一个结果集,该结果集包含与连接条件匹配的左表和右表的每个组合的一行。没有看到数据或更多信息,很难说出你期望的确切错误,但我猜它是以下之一:

1)project_team中有两个条目具有相同的user_id。

2)你在project_team中的条目存储了user_id和project_id,你需要加入它们而不仅仅是user_id。

答案 1 :(得分:1)

project_board_members表示在实体 - 关系建模世界中称为“关联实体”的内容。存在实现多对多关系(在这种情况下,在项目和用户实体之间。因此它是依赖实体,也就是说它的实例的存在是基于它所引用的每个实体(用户和项目)的实例的存在。

因此,包含与这些实体(member_idproject_id)相关的外键的列必须构成主键的一部分或全部。

通常,关联实体的实例是与其相关的实体的唯一WRT。在您的情况下,关系定义将是:

  • 每个用户都坐在0对多项目的董事会上;
  • 每个项目的董事会由0对多用户组成

也就是说特定用户可能不会多次出现在特定项目的董事会上。将其他列(例如id列)添加到主键的唯一原因是,如果用户:项目关系不是唯一的。

要强制执行此规则 - 用户可能只需在特定项目上坐一次 - 表架构应如下所示:

create table project_board_member
(
  member_id  int not null foreign key references user    ( user_id ) ,
  project_Id int not null foreign key references project ( project_id ) ,
  created_at ...

  ...

  primary key ( member_id , project_id ) ,
)
}

id列是多余的。

答案 2 :(得分:0)

出于调试目的,请执行

SELECT GROUP_CONCAT(pbm.member_id) AS member_ids,
       GROUP_CONCAT(u.name) as names,
       GROUP_CONCAT(u.surname) as surnames,
       GROUP_CONCAT(u.country) as countries,
       GROUP_CONCAT(pt.tasks_completed) as tasks
FROM project_board_members pbm
JOIN users u
    ON (u.id = pbm.member_id)
JOIN project_team pt
    ON (pt.user_id = pbm.member_id)
WHERE pbm.project_id = '5'
GROUP BY pbm.member_id

在结果中列出多个条目的所有字段都会弄乱结果集中的rowcount。

修复您可以执行的操作:

SELECT pbm.member_id
       u.name,
       u.surname,
       u.country,
       pt.tasks_completed
FROM (SELECT 
        p.project_id, p.member_id 
        FROM project_board_members p 
        WHERE p.project_id = '5'
      LIMIT 1
     ) AS pbm
JOIN users u
    ON (u.id = pbm.member_id)
JOIN project_team pt
    ON (pt.user_id = pbm.member_id)