代码之家  ›  专栏  ›  技术社区  ›  Eric Ness

同一表中使用不同条件的一个sql查询中的多个聚合函数

  •  10
  • Eric Ness  · 技术社区  · 16 年前

    我正在创建一个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
    

    任何洞察都将不胜感激。

    3 回复  |  直到 16 年前
        1
  •  22
  •   Jeremy    16 年前
    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
    

    这样,如果你改变你的情况,它只在一个地方。

        2
  •  4
  •   Tomalak    16 年前

    把不同的东西分开分组,加入小组。

    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关键字是caps而其他关键字不是,那么可读性也会提高。恕我直言。

        3
  •  0
  •   HLGEM    16 年前
    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