SQL 带条件的 where 子句中的 SUM

SQL SUMs in where clause with conditionals

我想获取 XYZ 业务的 "totals" 报告。他们需要季节、任期、员工的不同计数以及员工的总工时,只有当员工的工时减少时!=任何增加等于减少的时间。

尝试做这样的事情:

select year,
   season,
   (select count(distinct empID)
  from tableA
 where a.season = season
   and a.year = year) "Employees",
   (select sum(hours)
   from(
     select distinct year,season,empID,hours
       from tableA
              where code like 'Drop%'
    )
  where a.season = season
    and a.year = year) "Dropped"

from tableA a
-- need help below
where (select sum(hours)
   from(
     select distinct year,season,empID,hours
       from tableA
      where code like 'Drop%'
    )
   where a.season = season
     and a.year = year
     and a.emplID = emplID)
!=
 (select sum(hours)
   from(
     select distinct year,season,empID,hours
       from tableA
      where code like 'Add%'
    )
   where a.season = season
     and a.year = year
     and a.emplID = emplID)
  group by year,season

看来我没有正确地执行我的 where 子句。我不相信我正确地将 emplID 加入每个 emplID 以排除那些 "drops" <> "adds"

编辑: 示例数据:
年、季节、EmplID、小时、代码
2015, 秋季, 001,10,下降
20150 秋季,001,10,添加
2015,秋季,002,5,坠落
2015,秋季,003,10,下降

总小时数应为 15。EmplyID 001 应从总计中删除,因为他的下降正好等于添加。

我认为你可以只用条件聚合来做你想做的事。像这样:

select year, season, count(distinct empID) as Employees,
       sum(case when code like 'Drop%' then hours end) as Dropped
from tableA
group by year, season;

很难准确地说出你想要什么,因为你没有样本数据和想要的结果(或者更好的是,SQL Fiddle)。您可能还需要一个 having 子句:

having (sum(case when code like 'Drop%' then hours end) <>
        sum(case when code like 'Add%' then hours end) 
       )

你想要这样的结果吗?

SELECT
   year
   ,season
   ,COUNT(DISTINCT empID) AS Employees
   ,SUM(CASE WHEN code LIKE 'Drop%' THEN hours ELSE 0 END) AS Dropped
FROM
   TableA
GROUP BY
   year
   ,season
HAVING
   (
   SUM(CASE WHEN code LIKE 'Drop%' THEN hours ELSE 0 END) 
   - SUM(CASE WHEN code LIKE 'Add%' THEN hours ELSE 0 END)
   ) <> 0

我通过一些分析设法解决了这个问题 .. ;)

  with tableA as ( 
           select 2015 year, 1 season, 1234 empID, 2 hours  , 'Add' code from dual union all
           select 2015 year, 1 season, 1234 empID, 3 hours  , 'Add' code from dual union all
           select 2015 year, 1 season, 1234 empID, 4 hours  , 'Add' code from dual union all
           select 2015 year, 1 season, 1234 empID, 2 hours  , 'Drop' code from dual union all
           select 2015 year, 1 season, 2345 empID, 5 hours  , 'Add' code from dual union all
           select 2015 year, 1 season, 2345 empID, 3.5 hours, 'Add' code from dual union all
           select 2015 year, 2 season, 1234 empID, 7 hours  , 'Add' code from dual union all
           select 2015 year, 2 season, 1234 empID, 5 hours  , 'Add' code from dual union all
           select 2015 year, 2 season, 2345 empID, 5 hours  , 'Add' code from dual union all
           select 2015 year, 2 season, 7890 empID, 3 hours  , 'Add' code from dual union all
           select 2014 year, 1 season, 1234 empID, 1 hours  , 'Add' code from dual union all
           select 2014 year, 1 season, 1234 empID, 2 hours  , 'Add' code from dual union all
           select 2014 year, 1 season, 1234 empID, 4 hours  , 'Add' code from dual
        ),
     w_group as (     
        select year, season, empID, hours, code,
               lead(hours) over (partition by year, season, empID, hours 
                             order by case when code like 'Drop%' then 'DROP'
                                           when code like 'Add%' then 'ADD'
                                           else NULL end ) new_hours
          from tableA
        )
  select year, season, count(distinct empID),
              sum(hours-nvl(new_hours,0)) total_hours
    from w_group
   where code like 'Add%'
   group by year, season
  /

        YEAR     SEASON COUNT(DISTINCTEMPID) TOTAL_HOURS
  ---------- ---------- -------------------- -----------
        2015          1                    2        15.5
        2014          1                    1           7
        2015          2                    3          20

(第一部分 "with tableA" 只是伪造了一些数据,因为你没有提供任何数据):)

[编辑] 根据您的数据和您的解释进行更正 - 简而言之,您正在计算 DROP,(减去 ADD),我在做相反的事情 [edit2] 将下面的查询替换为基于 comment/feedback 的小调整:如果他们的 DROP-ADD 为零则不计算 empID)

 with tableA as ( 
     select 2015 year, 'FALL' season, '001' empID, 10 hours, 'Drop' code from dual union all
     select 2015 year, 'FALL' season, '001' empID, 10 hours, 'Add' code from dual union all
     select 2015 year, 'FALL' season, '002' empID, 5  hours, 'Drop' code from dual union all
     select 2015 year, 'FALL' season, '003' empID, 10 hours, 'Drop' code from dual
       ),
    w_group as (     
       select year, season, empID, hours, code,
              lag(hours) over (partition by year, season, empID, hours 
                            order by case when code like 'Drop%' then 'DROP'
                                          when code like 'Add%' then 'ADD'
                                          else NULL end ) new_hours
         from tableA
       )
 select year, season, count(distinct empID),
             sum(hours-nvl(new_hours,0)) total_hours
   from w_group
  where code like 'Drop%'
    and hours - nvl(new_hours,0) > 0
  group by year, season
 /

        YEAR SEAS COUNT(DISTINCTEMPID) TOTAL_HOURS
  ---------- ---- -------------------- -----------
        2015 FALL                    2          15

[/edit]