MySQL多对多连接有AND查询无法正常工作

时间:2012-04-17 15:36:08

标签: mysql join where having

我有以下五个表:

 company        type    branch      company_type       company_branch
 -------        ----    ------     -------------       --------------
  c_id          t_id     b_id       c_id | t_id         c_id | b_id     
  ----          ---      ----       -----------        --------------
   1             1        1            1  1              1     1
   2             2        2            1  2              1     2
                 3        3            2  1              2     1
                                       2  3              2     3

以下两个查询可以正常运行:

SELECT DISTINCT `co`.`c_id`
FROM (`company` co)
JOIN `company_type` t ON `t`.`c_id` = `co`.`c_id`
WHERE `co`.`status` = 1
GROUP BY `co`.`c_id`
HAVING sum(if(`t`.`t_id` in (1,2),1,0)) = 2       (---> returns 1 ) Correct !

SELECT DISTINCT `co`.`c_id`
FROM (`company` co)
JOIN `company_branch` b ON `b`.`c_id` = `co`.`id`
WHERE `co`.`status` = 1
GROUP BY `co`.`id`
HAVING sum(if(`b`.`b_id` in (1,2),1,0)) = 2        (---> returns 1 ) Correct !

但是当我尝试将它们组合起来时,它会给我一个空洞的结果:

SELECT DISTINCT `co`.`c_id`
FROM (`company` co)
JOIN `company_branch` b ON `b`.`c_id` = `co`.`id`
JOIN `company_type` t ON `t`.`c_id` = `co`.`id`
WHERE `co`.`status` = 1
GROUP BY `co`.`id`
HAVING sum(if(`b`.`b_id` in (1,2),1,0)) = 2 AND sum(if(`t`.`t_id` in (1,2),1,0)) = 2

我的猜测是两个条件之间的AND是罪魁祸首!!有人有线索吗?或解决方法?

预期结果:1

3 个答案:

答案 0 :(得分:2)

它可能是因为你得到了一个无意中的笛卡尔连接,从而产生了4条记录。每个分支和类型两个。我的猜测是你的数量是4个...当然,试试

SELECT `co`.`c_id`,
       sum(if(`b`.`b_id` in (1,2),1,0)) as BranchCount,
       sum(if(`t`.`t_id` in (1,2),1,0)) as TypeCount
   FROM (`company` co)
      JOIN `company_branch` b ON `b`.`c_id` = `co`.`id`
      JOIN `company_type` t ON `t`.`c_id` = `co`.`id`
   WHERE `co`.`status` = 1
   GROUP BY `co`.`id`

要修复它,我会调整如下:

select co.C_ID
   from
      company co
         join company_branch b 
            on co.id = b.c_id
           and b.b_id in ( 1, 2 )
         join company_type t 
            on co.id  = t.c_id
           and t.t_id in ( 1, 2 )
   where
      co.status = 1
   GROUP BY 
      co.id
   HAVING
           count( distinct b.b_id ) = 2
       AND count( distinct t.t_id ) = 2

答案 1 :(得分:0)

此查询应满足您的要求。而不是在HAVING子句中指定过滤条件,首先计算每个co_id的总和,并使用子查询对它们应用WHERE子句过滤条件。这应该可以正常工作。

SELECT Z.* FROM
(
SELECT `co`.`c_id`,
       sum(if(`b`.`b_id` in (1,2),1,0)) as BranchCount,
       sum(if(`t`.`t_id` in (1,2),1,0)) as TypeCount
   FROM (`company` co)
      JOIN `company_branch` b ON `b`.`c_id` = `co`.`id`
      JOIN `company_type` t ON `t`.`c_id` = `co`.`id`
   WHERE `co`.`status` = 1
   GROUP BY `co`.`id`
) Z
WHERE Z.BranchCount=2 AND Z.TypeCount=2;

答案 2 :(得分:0)

您发布的Btw查询有一些错误,所以我试图发布正确的错误,以便如果有人想尝试,他们可以做到这一点。 第一个:     SELECT DISTINCT coc_id     FROM(company co)     加入company_type t tc_id = coc_id     GROUP BY coc_id     总和(if(tt_id in(1,2),1,0))= 2 第二个:

SELECT DISTINCT `co`.`c_id`
FROM (`company` co)
JOIN `company_branch` b ON `b`.`c_id` = `co`.`c_id`
GROUP BY `co`.`c_id`
HAVING sum(if(`b`.`b_id` in (1,2),1,0)) = 2

我已排除状态列,因为我没有在表结构中使用它。

现在我不确定你的业务逻辑是什么,但我提出了你的最终SQL,如下所示:

SELECT DISTINCT `co`.`c_id`,sum(if(`cb`.`b_id` in (1,2),1,0)) cb_sum,sum(if(`ct`.`t_id` in (1,2),1,0)) ct_sum
FROM (`company` co)
LEFT JOIN `company_branch` cb ON `cb`.`b_id` = `co`.`c_id`
LEFT JOIN `company_type` ct ON `ct`.`t_id` = `co`.`c_id`
GROUP BY `co`.`c_id`
HAVING sum(if(`cb`.`b_id` in (1,2),1,0)) = 2 AND sum(if(`ct`.`t_id` in (1,2),1,0)) = 2

现在,如果您运行带有HAVING子句的SQL,您应该看到如下输出:

c_id      cb_sum       ct_sum
1         4            4
2         1            1

因此,如果您将条件更改为“> 2”而不是“= 2”,您应该得到您想要的内容,但另一个选项是您使用UNION将结果集合并如下:

SELECT DISTINCT `co`.`c_id`
FROM (`company` co)
JOIN `company_type` t ON `t`.`c_id` = `co`.`c_id`
GROUP BY `co`.`c_id`
HAVING sum(if(`t`.`t_id` in (1,2),1,0)) = 2
UNION
SELECT DISTINCT `co`.`c_id`
FROM (`company` co)
JOIN `company_branch` b ON `b`.`c_id` = `co`.`c_id`
GROUP BY `co`.`c_id`
HAVING sum(if(`b`.`b_id` in (1,2),1,0)) = 2