来自多个表的值总和,按公共列分组

时间:2018-12-12 23:14:09

标签: sql-server tsql join pivot aggregate

我在MS SQL Server 2014中有三个表。每个表都包含几个数字值,一个描述和一个日期。为了简洁起见,让我们假设以下表格:

table "beverages"

day        beverage amount
---------- -------- ------
2018-12-01 water    2
2018-12-01 tea      1
2018-12-01 coffee   7
2018-12-02 water    4
2018-12-02 tea      2


table "meals"

day        meal   amount
---------- ------ ------
2018-12-01 burger 1
2018-12-01 bread  2
2018-12-02 steak  1


table "fruit"

day        fruit  amount
---------- ------ ------
2018-12-01 apple  4
2018-12-01 banana 1
2018-12-02 apple  2

然后我有另一个只包含日期列表的表。

table "dates"

day
----------
2018-12-01
2018-12-02

我需要一个查询,该查询为dates表中的每一行返回一行,并且每一行中都有日期,饮料总量,进餐总量和总量那天的水果。我不在乎饮料,食物和水果的不同类型,而只是总数。结果应该是:

expected result

day        beverages   meals       fruit
---------- ----------- ----------- -----------
2018-12-01 10          3           5
2018-12-02 6           1           2 

但是我收到了

received result

day        beverages   meals       fruit
---------- ----------- ----------- -----------
2018-12-01 40          18          30
2018-12-02 6           2           4

我已经知道问题出在哪里,只是不知道如何解决。更糟糕的是,我确定我曾经知道答案,但是现在我什至找不到正确的搜索词来让Google告诉我...

当我这样查询时(我使用表变量进行测试)

SELECT 
     [d].[day]
    ,SUM([b].[amount]) AS [beverages]
    ,SUM([m].[amount]) AS [meals]
    ,SUM([f].[amount]) AS [fruit]
FROM @dates AS [d]
LEFT OUTER JOIN @beverages AS [b]
    ON [d].[day] = [b].[day]
LEFT OUTER JOIN @meals AS [m]
    ON [d].[day] = [m].[day]
LEFT OUTER JOIN @fruit AS [f]
    ON [d].[day] = [f].[day]
GROUP BY [d].[day]

它多次对来自不同表的每一行求和,因为它会返回三个表的所有可能组合。删除SUM()和GROUP BY证明:

day        beverages   meals       fruit
---------- ----------- ----------- -----------
2018-12-01 2           1           4
2018-12-01 2           1           1
2018-12-01 2           2           4
2018-12-01 2           2           1
2018-12-01 1           1           4
2018-12-01 1           1           1
2018-12-01 1           2           4
2018-12-01 1           2           1
2018-12-01 7           1           4
2018-12-01 7           1           1
2018-12-01 7           2           4
2018-12-01 7           2           1
2018-12-02 4           1           2
2018-12-02 2           1           2

那么,我需要在查询中进行哪些更改以使其对三个表中的每个表的值求和而不将其与其他表中的行数相乘?

2 个答案:

答案 0 :(得分:2)

对表进行分组,然后再加入,就像这样:

SELECT 
     [d].[day]
    ,[b].[amount] AS [beverages]
    ,[m].[amount] AS [meals]
    ,[f].[amount] AS [fruit]
FROM @dates AS [d]
LEFT OUTER JOIN (SELECT day, SUM(amount) as amount FROM @beverages GROUP BY day) AS [b]
    ON [d].[day] = [b].[day]
LEFT OUTER JOIN (SELECT day, SUM(amount) as amount FROM @meals GROUP BY day) AS [m]
    ON [d].[day] = [m].[day]
LEFT OUTER JOIN (SELECT day, SUM(amount) as amount FROM @fruit GROUP BY day) AS [f]
    ON [d].[day] = [f].[day]

答案 1 :(得分:1)

PIVOT呢?

示例

Select *
 From (
        Select day,Item='beverage',amount from beverages
        Union All
        Select day,Item='meals'   ,amount from meals
        Union All
        Select day,Item='fruit'   ,amount from fruit
      ) src
Pivot ( sum(amount) for Item in ([beverages],[meals],[fruit]) ) pvt