2010-04-16 110 views
9

我正在創建一個基於兩個聚合函數的值從表中提取記錄的SQL查詢。這些聚合函數從同一個表中提取數據,但是使用不同的過濾條件。我遇到的問題是SUM的結果比只包含一個SUM函數的結果大得多。我知道我可以使用臨時表創建此查詢,但我只是想知道是否有一個優雅的解決方案只需要一個查詢。使用不同條件的同一表中的一個SQL查詢中的多個聚合函數

我創建了一個簡化版本來演示這個問題。下面是表的結構:

EMPLOYEE TABLE 

EMPID 
1 
2 
3 

ABSENCE TABLE 

EMPID DATE  HOURS_ABSENT 
1  6/1/2009 3 
1  9/1/2009 1 
2  3/1/2010 2 

這裏是查詢:

SELECT 
    E.EMPID 
    ,SUM(ATOTAL.HOURS_ABSENT) AS ABSENT_TOTAL 
    ,SUM(AYEAR.HOURS_ABSENT) AS ABSENT_YEAR 

FROM 
    EMPLOYEE E 

    INNER JOIN ABSENCE ATOTAL ON 
     ATOTAL.EMPID = E.EMPID 

    INNER JOIN ABSENCE AYEAR ON 
     AYEAR.EMPID = E.EMPID 

WHERE 
    AYEAR.DATE > '1/1/2010' 

GROUP BY 
    E.EMPID 

HAVING 
    SUM(ATOTAL.HOURS_ABSENT) > 10 
    OR SUM(AYEAR.HOURS_ABSENT) > 3 

任何有識之士將不勝感激。

+0

這是有點混亂。根據給定的數據,您的預期結果是什麼? – Raja 2010-04-16 16:58:29

回答

19
SELECT 
    E.EMPID 
    ,SUM(ABSENCE.HOURS_ABSENT) AS ABSENT_TOTAL 
    ,SUM(case when year(Date) = 2010 then ABSENCE.HOURS_ABSENT else 0 end) AS ABSENT_YEAR 

FROM 
    EMPLOYEE E 

    INNER JOIN ABSENCE ON 
     ABSENCE.EMPID = E.EMPID 

GROUP BY 
    E.EMPID 

HAVING 
    SUM(ATOTAL.HOURS_ABSENT) > 10 
    OR SUM(case when year(Date) = 2010 then ABSENCE.HOURS_ABSENT else 0 end) > 3 

編輯:

這不是什麼大不了的事,但我討厭重複的條件,所以我們可以重構,如:

Select * From 
(
    SELECT 
     E.EMPID 
     ,SUM(ABSENCE.HOURS_ABSENT) AS ABSENT_TOTAL 
     ,SUM(case when year(Date) = 2010 then ABSENCE.HOURS_ABSENT else 0 end) AS ABSENT_YEAR 

    FROM 
     EMPLOYEE E 

     INNER JOIN ABSENCE ON 
      ABSENCE.EMPID = E.EMPID 

    GROUP BY 
     E.EMPID 
    ) EmployeeAbsences 
    Where ABSENT_TOTAL > 10 or ABSENT_YEAR > 3 

這樣,如果你改變你的情況的條件,它是在一個只有現貨。

+0

非常感謝!你已經向我介紹了「什麼時候」......你讓我擺脫了我遇到的大問題! – user979051 2012-11-20 17:08:58

0
SELECT E.EMPID , sum(ABSENT_TOTAL) , sum(ABSENT_YEAR) 
FROM 
(SELECT 
    E.EMPID 
    ,SUM(ATOTAL.HOURS_ABSENT) AS ABSENT_TOTAL 
    ,0 AS ABSENT_YEAR 

FROM 
    EMPLOYEE E 

    INNER JOIN ABSENCE ATOTAL ON 
     ATOTAL.EMPID = E.EMPID 
WHERE 
    AYEAR.DATE > '1/1/2010' 

GROUP BY 
    E.EMPID 

HAVING 
    SUM(ATOTAL.HOURS_ABSENT) > 10 

UNION ALL 

SELECT 0  
    ,SUM(AYEAR.HOURS_ABSENT) 
FROM 
    EMPLOYEE E  

     INNER JOIN ABSENCE AYEAR ON 
     AYEAR.EMPID = E.EMPID 

GROUP BY 
    E.EMPID 

HAVING 
    SUM(AYEAR.HOURS_ABSENT) > 3) a 

    GROUP BY A.EMPID 
4

將不同的東西分別分組,加入組。

SELECT 
    T.EMPID 
    ,T.ABSENT_TOTAL 
    ,Y.ABSENT_YEAR 
FROM 
    (
    SELECT 
     E.EMPID 
     ,SUM(A.HOURS_ABSENT) AS ABSENT_TOTAL 
    FROM 
     EMPLOYEE E 
     INNER JOIN ABSENCE A ON A.EMPID = E.EMPID 
    GROUP BY 
     E.EMPID 
    ) AS T 
    INNER JOIN 
    (
    SELECT 
     E.EMPID 
     ,SUM(A.HOURS_ABSENT) AS ABSENT_YEAR 
    FROM 
     EMPLOYEE E 
     INNER JOIN ABSENCE A ON A.EMPID = E.EMPID 
    WHERE 
     A.DATE > '1/1/2010' 
    GROUP BY 
     E.EMPID 
    ) AS Y 
    ON T.EMPLID = Y.EMPLID 
WHERE 
    ABSENT_TOTAL > 10 OR ABSENT_YEAR > 3 

此外,如果只有SQL關鍵字是大寫字母而其餘不是,則可讀性會增加。恕我直言。

相關問題