簡體   English   中英

具有非唯一日期的SQL Sum

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM