【问题标题】:SQL SUMs in where clause with conditionals带有条件的 where 子句中的 SQL SUM
【发布时间】:2015-02-03 16:18:50
【问题描述】:

我想获得企业 XYZ 的“总计”报告。他们需要季节、任期、不同的员工人数以及员工的总停工时间,只有当员工的停工时间!= 等于下降的任何添加时。

尝试做这样的事情:

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,FALL,002,5,下降
2015,FALL,003,10,下降

总小时数应为 15。应从总计中删除 EmplyID 001,因为他的掉落数与添加数完全相同。

【问题讨论】:

    标签: sql oracle sum subquery


    【解决方案1】:

    我设法通过一些分析来解决它.. ;)

      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] 用基于评论/反馈的细微调整替换了下面的查询:如果他们的 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
    

    [/编辑]

    【讨论】:

    • 我不认为这是我想要的...我在上面添加了示例数据
    • 啊,我明白了……只需要颠倒逻辑。我正在添加“ADDs”,减去“DROPs”.. 似乎你想要相反。所以使用 LAG,而不是领先,然后保留 DROP,而不是最后的 ADD .. viola .. 15.
    • 几乎就是这样! emplID 的总数应为 2。如果员工有添加 = 删除,则将其从所有计数中排除
    • 不用担心,将上面的查询替换为更改:在 where 子句中添加一个条件,只包括在 DROP - ADD 完成后剩下几个小时的条件。
    • 谢谢。我试图理解这个过程,“结束”在做什么?有没有办法在不使用 'over 的情况下做到这一点?
    【解决方案2】:

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

    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) 
           )
    

    【讨论】:

    • 添加了示例数据和一些解释
    【解决方案3】:

    你想要这样的结果吗?

    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
    

    【讨论】:

    • 类似这样的东西是的,但它还没有完全起作用......我在选择中的总和使用不同的 subqeury 来获得正确的结果。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多