在单个group by子句中计算不同值集的同一列

时间:2013-08-20 03:42:37

标签: sqlite

我有一个像这样的表(SQLite DB),

CREATE TABLE parser (ip text, user text, code text);

现在我需要计算有多少code的值为1, 2, or 3,有多少不是ip字段的分组。

但就我而言,我不能完全做到这一点,但有两个SQL短语。

例如

select count(*) as cnt, ip 
from parser 
where code in (1, 2, 3) 
group by ip 
order by cnt DESC 
limit 10

not in查询。

那么,我可以将两个查询合并为一个吗?

1 个答案:

答案 0 :(得分:1)

这将为您提供每ip两个计数,一个用于code的值为1,2或3的行,另一个用于所有其余的计数(除了1,2,3之外的所有内容)包括NULL。)

SELECT ip,
       COUNT(CASE WHEN code IN (1, 2, 3) THEN 1 ELSE NULL END) AS cnt_in, 
       COUNT(CASE WHEN code IN (1, 2, 3) THEN NULL ELSE 1 END) AS cnt_rest
FROM parser  
GROUP BY ip 
ORDER BY cnt_in DESC ;

这将为您提供3个计数,一个用于1,2,3,另一个用于剩余的整数值,第三个用于NULLcode的行:

SELECT ip,
       COUNT(CASE WHEN code IN (1, 2, 3) THEN 1 END) AS cnt_in, 
       COUNT(CASE WHEN code NOT IN (1, 2, 3) THEN 1 END) AS cnt_not_in,
       COUNT(CASE WHEN code IS NULL THEN 1 END) AS cnt_null
FROM parser  
GROUP BY ip 
ORDER BY cnt_in DESC ;

如果要将第一个结果(作为代码)限制为前10行,将第二个结果限制为其他前10行,则可以使用两个子查询和UNION

( SELECT ip,
         COUNT(*) AS cnt, 
         'in' AS type
  FROM parser
  WHERE code IN (1, 2, 3)
  GROUP BY ip 
  ORDER BY cnt DESC 
  LIMIT 10 
)
UNION ALL
( SELECT ip,
         COUNT(*) AS cnt, 
         'not in' AS type
  FROM parser
  WHERE code NOT IN (1, 2, 3)
  GROUP BY ip 
  ORDER BY cnt DESC 
  LIMIT 10 
) ;

SQL-Fiddle

进行测试