我有两个表-departments
和products
。
我正在尝试使用以下查询将两个表连接起来:
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
。有什么办法吗?我尝试了许多不同的联接,但无法获得想要的结果。
答案 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 column从bar.foo_id
到foo.foo_id
并获得以下结果:
foo.foo_id COUNT(bar.bar_id)
10 3
20 2
30 1
40 0
50 0