MySQL,加入多对多关系查询

时间:2017-07-26 22:37:42

标签: mysql sql

我有这个问题:

SELECT
    GROUP_CONCAT(DISTINCT
        `persons`.`name`,
        '[START_Name_END]',
        `persons`.`id`,
        '[START_Id_END]',
        `persons`.`isteacher`,
        '[START_IsTeacher_END]'
    SEPARATOR '[START_ROWSEPERATOR_END]') AS persons_values,
    `locations`.`name` AS locations_name,
    `locations`.`id` AS locations_id
FROM `locations`
INNER JOIN `locations_persons` ON `locations_persons`.`location_id` = `locations`.`id`
INNER JOIN `persons` ON `persons`.`id` = `locations_persons`.`person_id`  
GROUP BY `locations`.`id`
ORDER BY `locations`.`id`

我使用GROUP_CONCAT的原因是从persons表获取在关联表中有引用的所有行,在同一列中

我使用[START_Name_END], [START_Id_END]稍后在我的代码和[START_ROWSEPERATOR_END]中拆分结果,以确定它是同一行还是新行。

到目前为止一切正常。

问题是如果locations表中的任何行没有引用persons表中的任何行,我就不会在结果中获得该行!

我相信问题出现在JOIN中,无论该行是否在关联表中有引用,我应该使用什么来获取所有行?

非常感谢任何帮助!

1 个答案:

答案 0 :(得分:1)

尝试使用:

LEFT OUTER JOIN `locations_persons` ...

- 编辑

抱歉,我是新来回答这些StackOverflow的事情,并且在回复之前没有给予它应得的关注。

您的表结构是一个经典的多对多连接,因此如果给定位置没有人,那么位置表中只会有位置数据。因此,您需要为locations_persons上的连接和从locations_persons到人员的连接进行LEFT OUTER JOIN。

如果您仍然遇到麻烦,我会创建一个快速的MySQL数据库并测试一下......从现在开始我会这样做,但我想我现在应该更充分地回复因为我的问题早些时候部分回答不好。

- EDIT2

关于期望问题:当您离开外部联接时,任何失败的联接(即左侧的行,但右侧没有匹配)将使右侧的表返回所有空值。在这种情况下,您希望查询正确处理locations_personspersons中返回空值的所有字段。

如果GROUP_CONCAT没有处理好这个问题(我不熟悉它),你可能需要在IFNULL中包裹这些人。*字段,如果你遇到问题:< / p>

SELECT
  GROUP_CONCAT(
    DISTINCT `persons`.`name`,
    '[START_Name_END]',
    IFNULL(`persons`.`id`, ''),
    '[START_Id_END]',
    IFNULL(`persons`.`isteacher`, ''),
    '[START_IsTeacher_END]' SEPARATOR '[START_ROWSEPERATOR_END]'
  ) AS persons_values,
  `locations`.`name` AS locations_name,
  `locations`.`id` AS locations_id
FROM
  `locations`
  LEFT OUTER JOIN `locations_persons` ON
    `locations_persons`.`location_id` = `locations`.`id`
  LEFT OUTER JOIN `persons` ON
    `persons`.`id` = `locations_persons`.`person_id`
GROUP BY
  `locations`.`id`
ORDER BY
  `locations`.`id`