2013-11-24 81 views
1

我想寫一個SQL查詢,將總結從以下兩個例子表總產量: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' 

看來,查詢是雙總結在instan預算小時ces在一天內生產多個案例。我得到的表如下:

Total Production  BudgetHours 
30000    72 

我該如何解決這個問題?

回答

1

想想內什麼JOIN在做。

對於CaseLot中的每一行,它都會查找具有匹配日期的預算中的任何行。

如果你要刪除SQL您彙總報表,並且只顯示內部聯接,你會看到下面的結果集:

DateProduced kgProduced OperatingDate BudgetHours

2013年10月1 10000 10月1日, 2013 24

2013年10月1日10000 2013年10月1日24

2013年10月2日10000 2013年10月2日24

(dammit StackOverflow,爲什麼你沒有Markdown的表:()

運行你的聚合最重要的是,很容易看到你如何得到72小時的結果。

正確的查詢需要先聚合CaseLots表,然後加入到預算表中。

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 
0

這可以通過本可以輕鬆實現:

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 

有沒有必要加入兩個表。

+0

如果您只想要1行返回的數據,如果有大於1的情況,您可以使用TOP 1 – andrewb

0

試試這個:

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' 
0

其他的答案是這種特殊情況下簡單。但是,如果您需要CaseLots表中的10個不同值,則需要10個不同的子查詢。以下是一般情況下,更擴展的解決方案:無需SUM的BudgetHours

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的。如果您在查詢中使用的SELECT * FROM上方你會看到:

Date  DayKgProduced BudgetHours 
2013-10-01 20000   24 
2013-10-02 10000   24 

但你想要的總總,所以我們SUM那些日常的價值觀,正確地產生:

TotalProduction TotalBudgetHours 
30000   48 
1

問題是在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'