Sql server 按公共列分组的多个表的值总和
我在MS SQL Server 2014中有三个表。它们中的每一个都包含一对数值、一个描述和一个日期。为了简洁起见,让我们假设下表:Sql server 按公共列分组的多个表的值总和,sql-server,tsql,join,pivot,aggregate,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 "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
我已经知道问题是什么,只是不知道如何解决。更糟糕的是,我确信我曾经知道答案,但现在我甚至无法找到正确的搜索词让谷歌告诉我
当我这样做查询时(我使用表变量进行测试)
它对不同表中的每一行求和不止一次,因为它返回三个表的所有可能组合。删除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
那么,我需要在查询中做什么更改,使其对三个表中的每一个表的值求和,而不与其他表中的行数相乘呢?换成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
在连接前将表分组,如下所示:
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]
谢谢现在我读了你的答案,我想知道我怎么可能忘记了那件事。你刚刚救了我一天!还没有使用PIVOT查询,所以我选择了Richard的“加入前分组”解决方案,但这肯定是我应该习惯的,因为它看起来更灵活。谢谢你的回答@Patricketerbruch我相信有一天你会发现PIVOT会派上用场:)
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]