LEFT JOIN的结果重复

时间:2018-11-06 15:05:18

标签: mysql

我正在尝试查找表A中处于活动状态的成员,并确保它们位于表B中的相应用户组中。返回的行应不匹配:不在组56中的活动用户,或处于非活动状态属于第56组的用户。

表B本质上只是一个外键表,用户将根据分配给它们的组数显示多次。我只关心第56组。

我可以正常使用,除了事实是,我为每个用户返回的行数与他们所在的组总数相对应。

Table A                  Table B
-----------------        ------------------------
m_id|name|email|active   group_id | user_id | etc
 01 |Abby|a@b.c|  1         01    |   01    | etc
 02 |Bob |b@b.c|  1         56    |   01    | etc
 03 |Carl|c@b.c|  1         56    |   02    | etc
 04 |Dan |d@b.c|  0         02    |   02    | etc
                            66    |   02    | etc
                            99    |   02    | etc
                            01    |   03    | etc
                            56    |   04    | etc

MySQL查询如下:

SELECT * FROM B LEFT JOIN A
ON B.user_id = A.m_id
WHERE (B.group_id = 56 AND A.active != 1) 
OR
(B.user_id NOT IN 
(SELECT DISTINCT B.user_id FROM B 
LEFT JOIN A ON B.user_id = A.m_id 
WHERE B.group_id = 56) AND A.active = 1)

1 个答案:

答案 0 :(得分:0)

通过使用Group By和带有Having子句的条件过滤,可以简化当前的方法,并且可以导致更有效的解决方案

我们将使用Sum()函数并有条件检查是否连续group_id = 56。它将返回1或0,具体取决于它是true还是false。如果我们希望某个特定条件至少发生一次,那么此条件的Sum()应该大于0,反之亦然。

SELECT tA.m_id, 
       tA.name, 
       tA.email, 
       tA.active 
FROM tableA AS tA 
LEFT JOIN tableB AS tB 
  ON tA.m_id = tB.user_id 
GROUP BY tA.m_id, 
         tA.name, 
         tA.email, 
         tA.active 
HAVING 
  (tA.active = 1 AND 
   NOT SUM(tb.group_id = 56)) -- active and no row having group_id = 56
        OR 
  (tA.active = 0 AND 
   SUM(tb.group_id = 56))  -- inactive and atleast one row having group_id = 56
相关问题