MySQL查询按Department_id分组的“部门LEFT JOIN产品”并不返回所有部门的数据

时间:2018-12-22 20:42:04

标签: mysql join left-join

我有两个表-departmentsproducts。 我正在尝试使用以下查询将两个表连接起来:

SELECT departments.department_id, departments.department_name, departments.over_head_costs, SUM(products.product_sales) as product_sales, products.product_sales - departments.over_head_costs AS profit
FROM departments
LEFT JOIN products
ON departments.department_id = products.department_id
GROUP BY products.department_id

我遇到的问题是此查询仅返回某些部门的数据。我希望查看所有部门的数据,即使没有产品具有 department_id 。有什么办法吗?我尝试了许多不同的联接,但无法获得想要的结果。

请查看以下图像,显示我得到的当前输出: enter image description here

enter image description here

2 个答案:

答案 0 :(得分:1)

尝试将您的分组子句更改为:

  GROUP BY departments.department_id

答案 1 :(得分:1)

我很确定您的问题是您正在按products.department_id而不是departments.department_id进行分组。如果一个部门没有产品,则左联接将为该部门产生单个结果行(在分组之前),其中 all products.*列设置为NULL。如果您按这些列之一(甚至是部门ID)分组,则分组结果将将没有产品的所有部门合并在一起 ,因为products.department_id对所有部门来说都是NULL。

这里是a simple example to demonstrate this

CREATE TEMPORARY TABLE foo (
  foo_id INTEGER PRIMARY KEY
);
CREATE TEMPORARY TABLE bar (
  bar_id INTEGER PRIMARY KEY,
  foo_id INTEGER NULL
);
INSERT INTO foo (foo_id) VALUES (10), (20), (30), (40), (50);
INSERT INTO bar (bar_id, foo_id) VALUES
  (1, 10), (2, 10), (3, 10),
  (4, 20), (5, 20), (6, 30);

SELECT foo.foo_id, COUNT(bar.bar_id)
  FROM foo
  LEFT JOIN bar USING(foo_id)
  GROUP BY bar.foo_id 

如果运行此查询,则结果应如下所示:

foo.foo_id  COUNT(bar.bar_id)
40          0
10          3
20          2
30          1

嗯,等等... foo_id 50怎么了?好吧,发生的是,在分组之前,左联接产生了a result set like this

foo.foo_id  bar.foo_id  bar.bar_id
10          10          1
10          10          2
10          10          3
20          20          4
20          20          5
30          30          6
40          NULL        NULL
50          NULL        NULL

请注意,在bar.foo_id为NULL的情况下,共有行。如果随后将结果分组到该列,则这些行将被分组在一起,即使它们的foo.foo_id值确实不同。

然后,更严格的RDBMS可能会抱怨您正在选择未分组的列foo.foo_id,而没有将其包装在诸如COUNT()SUM()MySQL isn't that strict by default之类的聚合函数中并从每个组中为该列选择一个任意值。在上面的示例中,我有40个,但也可能是50个。

无论如何,解决方法很简单:只需将分组列更改为departments.department_id,您将获得期望的结果。或者,为了继续使用示例架构,我可以在上面的查询中change the grouping columnbar.foo_idfoo.foo_id并获得以下结果:

foo.foo_id  COUNT(bar.bar_id)
10          3
20          2
30          1
40          0
50          0