MySQL调用返回错误组合的结果,如果涉及的表为空,则返回全空行

时间:2016-06-23 15:53:16

标签: mysql join concatenation distinct

所以我在数据库中有这些数据包含这些数据:

building_officer_membership
+--------------------------------+-------------+------------+
| building_officer_membership_id | building_id | officer_id |
+--------------------------------+-------------+------------+
|                              1 |           1 |          1 |
|                              2 |           1 |          2 |
+--------------------------------+-------------+------------+

building
+-------------+-----------------+
| building_id | name            |
+-------------+-----------------+
|           1 | a_nice_building |
+-------------+-----------------+

officer
+------------+------------+-----------+
| officer_id | first_name | last_name |
+------------+------------+-----------+
|          1 | Brandon    | Thompson  |
|          2 | Mark       | Bobby     |
+------------+------------+-----------+

Manager
+------------+---------------+
| manager_id | full_name     |
+------------+---------------+
|          1 | Bill Lumbergh |
|          2 | Bob Page      |
+------------+---------------+

 officer manager membership
+-------------------------------+------------+------------+
| officer_manager_membership_id | officer_id | manager_id |
+-------------------------------+------------+------------+
|                             1 |          1 |          1 |
|                             2 |          2 |          2 |
+-------------------------------+------------+------------+

我有一个MySQL调用,返回与建筑物相关联的每个人员(在building_officer_membership表中。)为了使其更具信息性,我还在每个结果中列出了这些人员所在的经理。

当我进行此SQL调用时,

SELECT building_officer_membership.building_officer_membership_id,
building_officer_membership.building_id,
building_officer_membership.officer_id,
GROUP_CONCAT(DISTINCT manager.full_name) as manager_name,
GROUP_CONCAT(DISTINCT manager.manager_id) AS manager_id
from building_officer_membership
JOIN building on building.building_id = building_officer_membership.building_id
JOIN officer on officer.officer_id = building_officer_membership.officer_id
JOIN officer_manager_membership on officer.officer_id = officer_manager_membership.officer_id
LEFT JOIN manager ON officer_manager_membership.manager_id = manager.manager_id

我希望有两个结果如下:

+--------------------------------+-------------+------------+------------------------+------------+
| building_officer_membership_id | building_id | officer_id | manager_name           | manager_id |
+--------------------------------+-------------+------------+------------------------+------------+
|                              1 |           1 |          1 | Bill Lumbergh          | 1          |
|                              2 |           1 |          2 | Bob Page               | 2          |
+--------------------------------+-------------+------------+------------------------+------------+

相反,我明白了:

+--------------------------------+-------------+------------+------------------------+------------+
| building_officer_membership_id | building_id | officer_id | manager_name           | manager_id |
+--------------------------------+-------------+------------+------------------------+------------+
|                              1 |           1 |          1 | Bill Lumbergh,Bob Page | 1,2        |
+--------------------------------+-------------+------------+------------------------+------------+

将军官的所有管理人员组合成一个结果。

如果表是空的,并且我进行了SQL调用,我得到了这个,而不是空行:

+--------------------------------+-------------+------------+--------------+------------+
| building_officer_membership_id | building_id | officer_id | manager_name | manager_id |
+--------------------------------+-------------+------------+--------------+------------+
|                           NULL |        NULL |       NULL | NULL         | NULL       |
+--------------------------------+-------------+------------+--------------+------------+

我知道错误发生在GROUP_CONCAT部分,因为如果删除它们,

select building_officer_membership.building_officer_membership_id,
    building_officer_membership.building_id,
    building_officer_membership.officer_id
    from building_officer_membership
    JOIN building on building.building_id = building_officer_membership.building_id
    JOIN officer on officer.officer_id = building_officer_membership.officer_id;
+--------------------------------+-------------+------------+
| building_officer_membership_id | building_id | officer_id |
+--------------------------------+-------------+------------+
|                              1 |           1 |          1 |
|                              2 |           1 |          2 |
+--------------------------------+-------------+------------+

我得到了我期望的结果,只是没有管理者信息。

所以我不太清楚这里发生了什么。我的联盟是太贪婪还是什么?

我的MySQL版本是5.1.73。由于我无法控制的原因,我无法升级到最新版本。在我使用此SQL调用的webservice代码中,我可以解决这个涉及更多SQL调用的问题,如果可能的话,我宁愿一次性地执行此操作。

1 个答案:

答案 0 :(得分:0)

Annnnd我明白了。这真是愚蠢。

选择building_officer_membership.building_officer_membership_id,building_officer_membership.building_id,building_officer_membership.officer_id,GROUP_CONCAT(DISTINCT manager.full_name)作为manager_name,GROUP_CONCAT(DISTINCT manager.manager_id)AS manager_id来自building_officer_membership JOIN building on building.building_id = building_officer_membership.building_id JOIN Officer on officer.officer_id = building_officer_membership.officer_id在officer.officer_id = officer_manager_membership.officer_id上的JOIN officer_manager_membership,JOIN manager ON Officer_manager_membership.manager_id = officer.officer_id

group by officer.officer_id

TIL group_concat需要一个group by才能知道如何组织结果,否则它会尽可能少地返回。