[英]SQL Sum with non unique date
I'm trying to write a SQL query that will sum total production from the following two example tables: 我正在尝试编写一个SQL查询,该查询将汇总以下两个示例表中的总产量:
Table: CaseLots
DateProduced kgProduced
October 1, 2013 10000
October 1, 2013 10000
October 2, 2013 10000
Table: Budget
OperatingDate BudgetHours
October 1, 2013 24
October 2, 2013 24
I would like to output a table as follows: 我想输出如下表:
TotalProduction TotalBudgetHours
30000 48
Here is what I have for code so far: 到目前为止,这是我所拥有的代码:
SELECT
Sum(kgProduced) AS TotalProduction, Sum(BudgetHours) AS TotalBudgetHours
FROM
dbo.CaseLots INNER JOIN dbo.Budget ON dbo.CaseLots.DateProduced = dbo.Budget.OperatingDate
WHERE
dbo.Budget.OperatingDate BETWEEN '2013-10-01' AND '2013-10-02'
It seems that the query is double summing the budget hour in instances where more than one case lot is produced in a day. 在一天中产生多个案件的情况下,查询似乎是预算小时的两倍。 The table I'm getting is as follows:
我得到的表如下:
Total Production BudgetHours
30000 72
How do I fix this? 我该如何解决?
Think about what the INNER JOIN is doing. 想想INNER JOIN在做什么。
For every row in CaseLot, its finding any row in Budget that has a matching date. 对于CaseLot中的每一行,它会在Budget中找到具有匹配日期的任何行。
If you were to remove your aggregation statements in SQL, and just show the inner join, you would see the following result set: 如果要删除SQL中的聚合语句,而仅显示内部联接,则会看到以下结果集:
DateProduced kgProduced OperatingDate BudgetHours 日期生产的公斤生产的经营日期预算小时
October 1, 2013 10000 October 1, 2013 24 2013年10月1日10000 2013年10月1日24
October 1, 2013 10000 October 1, 2013 24 2013年10月1日10000 2013年10月1日24
October 2, 2013 10000 October 2, 2013 24 2013年10月2日10000 2013年10月2日24
(dammit StackOverflow, why don't you have Markdown for tables :( ) (该死的StackOverflow,为什么你没有Markdown的表:()
Running your aggregation on top of that it is easy to see how you get the 72 hours in your result. 在此基础上运行聚合很容易看到您如何获得72小时的结果。
The correct query needs to aggregate the CaseLots table first, then join onto the Budget table. 正确的查询需要首先聚合CaseLots表,然后再联接到Budget表。
SELECT DateProduced, TotalKgProduced, SUM(BudgetHours) AS TotalBudgetHours
FROM
(
SELECT DateProduced, SUM(kgProduced) AS TotalKgProduced
FROM CaseLots
GROUP BY DateProduced
) AS TotalKgProducedByDay
INNER JOIN
Budget
ON TotalKgProducedByDay.DateProduced = Budget.OperatingDate
WHERE DateProduced BETWEEN '1 Oct 2013' AND '2 Oct 2013'
GROUP BY DateProduced
The problem is in the INNER JOIN
produces a 3 row table since the keys match on all. 问题在于
INNER JOIN
产生3行表,因为所有键都匹配。 So there is three '24's with a sum of 72. 因此,存在三个“ 24”,总和为72。
To fix this, it would probably be easier to split this into two queries. 要解决此问题,将其分为两个查询可能会更容易。
SELECT Sum(kgProduced) AS TotalProduction
FROM dbo.CaseLots
WHERE dbo.CaseLots.OperatingDate BETWEEN '2013-10-01' AND '2013-10-02'
LEFT JOIN
SELECT Sum(BudgetHours) AS TotalBudgetHours
FROM dbo.Budget
WHERE dbo.Budget.OperatingDate BETWEEN '2013-10-01' AND '2013-10-02'
This could be easily achieved by this: 这可以通过以下方式轻松实现:
SELECT
(SELECT SUM(kgProduced) FROM dbo.CaseLots WHERE DateProduced BETWEEN '2013-10-01' AND '2013-10-02') AS TotalProduction,
(SELECT SUM(BudgetHours) FROM dbo.Budget WHERE OperatingDate BETWEEN '2013-10-01' AND '2013-10-02') AS TotalBudgetHours
There's no need for joining the two tables. 无需加入两个表。
Try this: 尝试这个:
select DateProduced,TotalProduction,TotalBudgetHours from
(select DateProduced,sum(kgProduced) as TotalProduction
from CaseLots group by DateProduced) p
join
(select OperatingDate,sum(BudgetHours) as TotalBudgetHours
from Budget group by OperatingDate) b
on (p.DateProduced=b.OperatingDate)
where p.DateProduced between '2013-10-01' AND '2013-10-02'
The other answers are simpler for this particular case. 对于这种特殊情况,其他答案更为简单。 However if you needed to
SUM
10 different values on the CaseLots
table, you'd need 10 different subqueries. 但是,如果你需要
SUM
在10个不同的值CaseLots
表,你需要10个不同的子查询。 The following is a general, more scaleable solution: 以下是一个通用的,可扩展的解决方案:
SELECT
SUM(DayKgProduced) AS TotalProduction,
SUM(BudgetHours) AS TotalBudgetHours
FROM (
SELECT
DateProduced,
SUM(kgProduced) AS DayKgProduced,
FROM dbo.CaseLots
WHERE DateProduced BETWEEN '2013-10-01' AND '2013-10-02'
GROUP BY DateProduced
) DailyTotals
INNER JOIN dbo.Budget b ON DailyTotals.DateProduced = b.OperatingDate
First you SUM
the production of each CaseLot
without having to SUM
the BudgetHours. 首先,你
SUM
生产的每一个CaseLot
不必SUM
的BudgetHours。 If you used a SELECT * FROM
in the query above you'd see: 如果在上面的查询中使用
SELECT * FROM
,则会看到:
Date DayKgProduced BudgetHours
2013-10-01 20000 24
2013-10-02 10000 24
But you want the overall total, so we SUM
those daily values, correctly producing: 但是,您需要总计,因此我们将这些每日值
SUM
,正确得出:
TotalProduction TotalBudgetHours
30000 48
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.