如何使用 CASE 语句而不必将其放入 GROUP BY

How to use CASE statement without having to put it into GROUP BY

我的查询有问题。这是我的代码:

select kpidate,reviewer as namareviewer, 
    count(formcode) as actual,
    round((0.2*count(formcode))) as target,
    CASE WHEN blibliknowledge !='' 
         THEN count(blibliknowledge)  
    END as blibli, 
    CASE WHEN solusi !=''
         THEN count(solusi)
    END as solusi
from kpi 
where kpidate >= '30/11/2015' AND kpidate<= '1/12/2015'
group by reviewer,kpidate,blibliknowledge,solusi

由于 CASE 表达式,我必须添加列 blibliknowledgesolusi,输出将如下所示:

我想按 namareviewer 分组,所以 'elbert.lukman' 将被分组。所以输出只有两行。列 bliblisolusi 也将被计算为 group by namareviewer.

您似乎想要进行条件聚合。根据条件使用 return 为 1 或 0 的表达式,然后将其包装在 SUM 聚合中。或者,有一个表达式 return NULL 和非空值,并将其包装在 COUNT 表达式中。

在 MySQL 中,日期文字应以 'yyyy-mm-dd' 格式提供。

举个例子:

SELECT k.kpidate
     , k.reviewer                                               AS namareviewer
     , COUNT(k.formcode)                                        AS actual
     , ROUND((0.2*COUNT(k.formcode)))                           AS target
     , SUM(CASE WHEN k.blibliknowledge != '' THEN 1 ELSE 0 END) AS blibli
     , COUNT(CASE WHEN k.solusi != '' THEN 'foo' ELSE NULL END) AS solusi
  FROM kpi k
 WHERE k.kpidate >= '2015-11-30'
   AND k.kpidate <= '2015-12-01'
 GROUP
    BY k.reviewer
     , k.kpidate

在MySQL中,我们可以用布尔表达式shorthandCASE表达式。 MySQL return 如果表达式的计算结果为 TRUE,则为整数值 1,如果表达式的计算结果为 FALSE,则 returns 为 0。如果表达式的计算结果为 NULL,则它 return 为 NULL。

SELECT k.kpidate
     , k.reviewer                              AS namareviewer
     , COUNT(k.formcode)                       AS actual
     , ROUND((0.2*COUNT(k.formcode)))          AS target
     , IFNULL(SUM(k.blibliknowledge != ''),0)  AS blibli
     , IFNULL(SUM(k.solusi          != ''),0)  AS solusi
  FROM kpi k
 WHERE k.kpidate >= '2015-11-30'
   AND k.kpidate <= '2015-12-01'
 GROUP
    BY k.reviewer
     , k.kpidate

您也可以缩短 Postgres 中的语法。这对 Postgres 和 MySQL 都适用:

SELECT kpidate
     , reviewer                             AS namareviewer
     , count(formcode)                      AS actual
     , round(count(formcode) * 0.2)         AS target
     , count(blibliknowledge <> '' OR NULL) AS blibli
     , count(solusi <> '' OR NULL)          AS solusi
FROM   kpi
WHERE  kpidate >= '2015-11-30'
AND    kpidate <  '2015-12-01'  -- typically, you'd exclude that upper bound
GROUP  BY reviewer, kpidate;

在 Postgres 9.4 中,您可以使用聚合 FILTER 子句的 SQL 标准实现:

SELECT kpidate
     , reviewer                                      AS namareviewer
     , count(formcode)                               AS actual
     , round(count(formcode) * 0.2)                  AS target
     , count(*) FILTER (WHERE blibliknowledge <> '') AS blibli
     , count(*) FILTER (WHERE solusi <> '')          AS solusi
FROM   kpi
WHERE  kpidate >= '2015-11-30'
AND    kpidate <  '2015-12-01'  -- typically, you'd exclude that upper bound
GROUP  BY 1, 2;  -- another optional syntax shortcut

还演示了一种语法 shorthand 当您 实际上 必须引用 SELECT 列表中的较长表达式时很有用 - 也可以回答您的原始问题.

更多:

  • Concatenate multiple result rows of one column into one, group by another column