MySQL - 多次将多行连接到单行

时间:2016-09-19 10:56:35

标签: mysql sql

我正在为单行尝试join多行信息,但每次其中一个连接中有更多行时,它似乎会成倍增加。

我的表格结构如下:

news
id  |  title  |  public
------------------------
1   |  Test   |  0


news_groups_map
id  |  news_id  |  members_group_id
------------------------------------
1   |  1        |  5
2   |  2        |  6


members_groups_map
id  |  member_id  |  group_id
------------------------------
1   |  750        |  5
2   |  750        |  6

我到目前为止的查询是:

SELECT 
n.title, 
n.public, 

CAST(GROUP_CONCAT(ngm.members_group_id) AS CHAR(1000)) AS news_groups,
CAST(GROUP_CONCAT(member_groups.group_id) AS CHAR(1000)) AS user_groups

FROM news n

LEFT JOIN news_groups_map ngm ON n.id = ngm.news_id

JOIN (
    SELECT group_id
    FROM members_groups_map
    WHERE member_id = 750
) member_groups

WHERE n.public = 0
GROUP BY n.id

然而,结果如下:

title  |  public  |  news_groups  |  user_groups
-------------------------------------------------
Test   |  0       |  5,6,5,6      |  6,6,5,5

正如您所看到的,news_groupuser_groups是重复的,因此,如果新闻文章分为3组,则user_groups也会成倍增加,并显示5,6,6,6,5,5之类的内容。 1}}。

如何对这些组进行分组,以便它们只显示一次?

此处的最终目标是比较news_groupsuser_groups。因此,如果至少有一个组匹配(意味着用户具有足够的权限),则应该返回一个返回true的布尔值,否则为false。我也不知道如何做到这一点,但是,我认为我应该首先对分组进行分类,因为一旦群组数量变大,就会有不必要的大量相同数据被选中。

谢谢!

2 个答案:

答案 0 :(得分:1)

在GROUP_CONCAT中使用DISTINCT

...
CAST(GROUP_CONCAT(DISTINCT ngm.members_group_id) AS CHAR(1000)) AS news_groups,
CAST(GROUP_CONCAT(DISTINCT member_groups.group_id) AS CHAR(1000)) AS user_groups
...

答案 1 :(得分:1)

最简单的方法是使用distinct

SELECT n.title, n.public, 
       GROUP_CONCAT(DISTINCT ngm.members_group_id) AS news_groups,     
       GROUP_CONCAT(DISTINCT mg.group_id) AS user_groups
FROM news n LEFT JOIN
     news_groups_map ngm
     ON n.id = ngm.news_id CROSS JOIN
     (SELECT group_id
      FROM members_groups_map
      WHERE member_id = 750
     ) mg
WHERE n.public = 0
GROUP BY n.id;

此查询实际上没有意义。首先,不需要子查询:

SELECT n.title, n.public, 
       GROUP_CONCAT(DISTINCT ngm.members_group_id) AS news_groups,     
       GROUP_CONCAT(DISTINCTD mg.group_id) AS user_groups
FROM news n LEFT JOIN
     news_groups_map ngm
     ON n.id = ngm.news_id CROSS JOIN
     members_groups_map mg
     ON member_id = 750
WHERE n.public = 0
GROUP BY n.id;

其次,CROSS JOIN(或等效地,JOIN没有ON子句)没有意义。通常情况下,我希望其他表之一的连接条件。