MySQL连接两个表,每个表都有group by

时间:2018-06-08 05:37:37

标签: mysql

我有两个包含部件号和数量的mysql表。我想对每个表qty sum(qty) ... group by partNumber求和,然后在部件号上加入两个表。

有时表A会有表b没有的部件号,反之亦然。下面是我期待的图像。

我尝试过类似的东西,但这会为每个表返回一行,我希望它返回1个组合行

SELECT *, null as macroQty, sum(qty) as cardinalQty 
  FROM parts.cardinal where fileinfoid IN 
   (select cardinalFiles from parts.reports where fileinfoid = 418) 
GROUP BY partNumber UNION ALL
SELECT *, sum(qty) as macroQty, null as cardinalQty 
  FROM parts.macro where fileinfoid IN 
    (select macroFiles from parts.reports where fileinfoid = 418 ) 
GROUP BY partNumber

我也尝试将它包装在外部选择中并按照外部选择中的部件编号进行分组,但这会导致第二个内部选择始终为null

SELECT * FROM (
  SELECT *, null as macroQty, sum(qty) as cardinalQty 
    FROM parts.cardinal where fileinfoid IN 
     (select cardinalFiles from parts.reports where fileinfoid = 418) 
  GROUP BY partNumber UNION ALL
  SELECT *, sum(qty) as macroQty, null as cardinalQty 
    FROM parts.macro where fileinfoid IN 
      (select macroFiles from parts.reports where fileinfoid = 418 ) 
  GROUP BY partNumber
) combined GROUP BY combined.partNumber

enter image description here

2 个答案:

答案 0 :(得分:1)

一种方法是在两个表中识别唯一的部件号(使用UNION,其中应用了不同的),然后使用相关的子查询来获得总和。例如

drop table if exists a,b;

create table a(id int,val int);
create table b(id int,val int);

insert into a values(1,10),(1,10),(3,10),(4,10);
insert into b values (2,10),(4,10),(4,10);

select (select sum(a.val) from a where a.id = s.id) aval,
         (select sum(b.val) from b where b.id = s.id) bval,
         s.id partno
from
(
select id from a
union select id from b
) s
order by s.id;

+------+------+--------+
| aval | bval | partno |
+------+------+--------+
|   20 | NULL |      1 |
| NULL |   10 |      2 |
|   10 | NULL |      3 |
|   10 |   20 |      4 |
+------+------+--------+
4 rows in set (0.00 sec)

答案 1 :(得分:0)

我会将此短语称为两个子查询之间的连接,每个子查询在各自的表中找到总和。但是,由于每个表不一定包含所有部件号,并且实际上每个表可能存在唯一的部件号,因此我们必须使用完全外部连接方法。

SELECT
    t1.partNumber,
    t1.cardinalQty,
    COALECSE(t2.macroQty, 0) AS macroQty
FROM
(
    SELECT partNumber, SUM(qty) AS cardinalQty
    FROM cardinal
    GROUP BY partNumber
) t1
LEFT JOIN
(
    SELECT partNumber, SUM(qty) AS macroQty
    FROM macro
    GROUP BY partNumber
) t2
    ON t1.partNumber = t2.partNumber

UNION ALL

SELECT
    t2.partNumber,
    0 AS cardinalQty,
    t2.macroQty
FROM
(
    SELECT partNumber, SUM(qty) AS cardinalQty
    FROM cardinal
    GROUP BY partNumber
) t1
RIGHT JOIN
(
    SELECT partNumber, SUM(qty) AS macroQty
    FROM macro
    GROUP BY partNumber
) t2
    ON t1.partNumber = t2.partNumber
WHERE t1.partNumber IS NULL;

请记住,在正常情况下,在设计良好的数据库中,您应该很少遇到需要使用完全外连接的情况。实际上,一个完整的外部联接尖​​叫着存在设计问题。在这种情况下,您没有包含所有零件编号的单个零件表。该表应该存在,所以除非你喜欢大丑查询,否则你应该创建一个零件表,其中partNumber是主键。