SQL两个条件聚合的总和

时间:2018-11-22 10:18:58

标签: sql oracle oracle11g

所以昨天我了解了条件聚合。我对SQL相当陌生。

这是我的查询:

select 
    Year_CW,
    sum(case when col = 0 then 1 else 0 end) as "Total_sampled(Checked)",
    sum(case when col = 1 then 1 else 0 end) as "Total_unsampled(Not_Checked)",       
    sum(case when col = 0 AND col2 = 'accepted' then 1 else 0 end) as "Accepted",
    sum(case when col = 0 AND col2 = 'accepted with comments' then 1 else 0 end) as "Accepted with comments",
    sum(case when col = 0 AND col2 = 'request for rework' then 1 else 0 end) as "Request for rework",
    sum(case when col = 0 AND col2 = 'rejected' then 1 else 0 end) as "Rejected",
    sum(case when col = 0 Or col = 1 then 1 else 0 end) as "Total_DS"
from 
    (select 
         Year_CW, SAMPLED as col, APPROVAL as col2 
     from 
         View_TEST tv) tv
group by 
    Year_CW 
order by 
    Year_CW desc

我基本上只是在计算按周分组的一些KPI。

在“ Total_DS”行中查找。它本质上是前两个和“ Total_sampled(Checked)”和“ Total_unsampled(Not_Checked)”之和。

有没有一种方法可以将前两个总和中的两列相加以获得第三个总和,而不是尝试再次获取数据?我认为明智的做法将是可怕的做法。这个数据库无关紧要,但是我不想从一开始就学习不好的代码实践。

感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

由于您已经拥有了所有可用数据,因此您可能不会在性能上受到重大影响,只是重复进行案例评估。

但是您不能在同一查询级别中引用前两列的列别名。

如果您无法按照@Zeki的建议进行简单计数,因为您不确定是否可能存在非零和一的值(尽管这看起来像是二进制的true / false等效项,所以很可能是检查约束,将您限制为这些值),或者,如果您只是对更一般的情况更感兴趣,则可以按照@jarhl的建议使用内联视图:

select Year_CW,
       "Total_sampled(Checked)",
       "Total_unsampled(Not_Checked)",
       "Accepted",
       "Accepted with comments",
       "Request for rework",
       "Rejected",
       "Total_sampled(Checked)" + "Total_unsampled(Not_Checked)" as "Total_DS"
from (
  select Year_CW,
         sum(case when col = 0 then 1 else 0 end) as "Total_sampled(Checked)",
         sum(case when col = 1 then 1 else 0 end) as "Total_unsampled(Not_Checked)",       
         sum(case when col = 0 AND col2 = 'accepted' then 1 else 0 end) as "Accepted",
         sum(case when col = 0 AND col2 = 'accepted with comments' then 1 else 0 end)
           as "Accepted with comments",
         sum(case when col = 0 AND col2 = 'request for rework' then 1 else 0 end)
           as "Request for rework",
         sum(case when col = 0 AND col2 = 'rejected' then 1 else 0 end) as "Rejected"
  from (
    select Year_CW, SAMPLED as col, APPROVAL as col2 
    from View_TEST tv
  ) tv
  group by Year_CW 
)
order by Year_CW desc;

内部查询获取数据并计算条件合计值。外部查询只从内部查询中获取这些值,然后通过将内部查询中的rwo值加在一起将Total_DS列添加到结果集中。


通常应避免使用带引号的标识符,如果在结果集中确实需要使用带引号的标识符,则应在可能的最后时刻应用它们-因此,请在内部查询中使用未加引号的标识符,并在外部查询中使用qupted别名。就个人而言,如果查询的重点是计算事物,我宁愿使用条件计数而不是条件和。我也不确定为什么您已经有一个针对您的视图的子查询,该子查询只是更改了列名并使主查询更加晦涩难懂。所以我可以这样:

select year_cw,
       total_sampled_checked as "Total_sampled(Checked)",
       total_unsampled_not_checked as "Total_unsampled(Not_Checked)",
       accepted as "Accepted",
       accepted_with_comments as "Accepted with comments",
       request_for_rework as "Request for rework",
       rejected as "Rejected",
       total_sampled_checked + total_unsampled_not_checked as "Total_DS"
from (
  select year_cw,
         count(case when sampled = 0 then 1 end) as total_sampled_checked,
         count(case when sampled = 1 then 1 end) as total_unsampled_not_checked,       
         count(case when sampled = 0 and approval = 'accepted' then 1 end) as accepted,
         count(case when sampled = 0 and approval = 'accepted with comments' then 1 end)
           as accepted_with_comments,
         count(case when sampled = 0 and approval = 'request for rework' then 1 end)
           as request_for_rework,
         count(case when sampled = 0 and approval = 'rejected' then 1 end) as rejected
  from view_test
  group by year_cw 
)
order by year_cw desc;

请注意,在案例表达式中,then 1可以是then <anything that isn't null>,因此您可以执行then sampled或其他任何操作。我省略了隐式else null。由于count()会忽略null,因此case表达式要做的就是将要包括在计数中的行的值取为任何非null值。

答案 1 :(得分:0)

您可以在下面尝试

select Year_CW,
       sum(case when col = 0 then 1 else 0 end) as "Total_sampled(Checked)",
       sum(case when col = 1 then 1 else 0 end) as "Total_unsampled(Not_Checked)",       
       sum(case when col = 0 AND col2 = 'accepted' then 1 else 0 end) as "Accepted",
       sum(case when col = 0 AND col2 = 'accepted with comments' then 1 else 0 end) as "Accepted with comments",
       sum(case when col = 0 AND col2 = 'request for rework' then 1 else 0 end) as "Request for rework",
       sum(case when col = 0 AND col2 = 'rejected' then 1 else 0 end) as "Rejected",
       sum(sum(case when col = 0 then 1 else 0 end) = 0 Or sum(case when col = 1 then 1 else 0 end) = 1 then 1 else 0 end) as "Total_DS"

from (select Year_CW, SAMPLED as col, APPROVAL as col2 
      from View_TEST tv
     ) tv
group by Year_CW 
order by Year_CW desc