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

时间:2015-12-01 02:08:30

标签: mysql sql database postgresql aggregate-functions

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

d = f.readline().replace("\n", ",").split(',')

由于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 表达式,我必须添加列blibliknowledgesolusi,输出将如下:

enter image description here

我希望按CASE进行分组,以便将'elbert.lukman'分组。所以输出只有两行。列namareviewerblibli也将由namareviewer 计算为组。

2 个答案:

答案 0 :(得分:1)

看起来你想做条件聚合。使用根据条件返回1或0的表达式,然后将其包装在SUM聚合中。或者,让表达式返回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中,我们可以用布尔表达式简写CASE表达式。如果表达式求值为TRUE,则MySQL返回整数值1;如果表达式求值为FALSE,则返回0。如果表达式求值为NULL,则返回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

答案 1 :(得分:0)

您也可以缩短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

实际必须引用SELECT列表中的长表达式时,还演示了一个有用的语法简写 - 也回答了原始问题。

更多: