[英]SQL Sum with non unique date
我正在尝试编写一个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
我想输出如下表:
TotalProduction TotalBudgetHours
30000 48
到目前为止,这是我所拥有的代码:
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'
在一天中产生多个案件的情况下,查询似乎是预算小时的两倍。 我得到的表如下:
Total Production BudgetHours
30000 72
我该如何解决?
想想INNER JOIN在做什么。
对于CaseLot中的每一行,它会在Budget中找到具有匹配日期的任何行。
如果要删除SQL中的聚合语句,而仅显示内部联接,则会看到以下结果集:
日期生产的公斤生产的经营日期预算小时
2013年10月1日10000 2013年10月1日24
2013年10月1日10000 2013年10月1日24
2013年10月2日10000 2013年10月2日24
(该死的StackOverflow,为什么你没有Markdown的表:()
在此基础上运行聚合很容易看到您如何获得72小时的结果。
正确的查询需要首先聚合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
问题在于INNER JOIN
产生3行表,因为所有键都匹配。 因此,存在三个“ 24”,总和为72。
要解决此问题,将其分为两个查询可能会更容易。
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'
这可以通过以下方式轻松实现:
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
无需加入两个表。
尝试这个:
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'
对于这种特殊情况,其他答案更为简单。 但是,如果你需要SUM
在10个不同的值CaseLots
表,你需要10个不同的子查询。 以下是一个通用的,可扩展的解决方案:
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
首先,你SUM
生产的每一个CaseLot
不必SUM
的BudgetHours。 如果在上面的查询中使用SELECT * FROM
,则会看到:
Date DayKgProduced BudgetHours
2013-10-01 20000 24
2013-10-02 10000 24
但是,您需要总计,因此我们将这些每日值SUM
,正确得出:
TotalProduction TotalBudgetHours
30000 48
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.