计数不同的ID,然后按不同的ID分组,产生错误的计数

时间:2018-09-20 10:02:14

标签: sql sqlite

我有一个SQLite数据库表,该表的结构与以下类似...

name     MicrosoftId     EventId

red      1               10001
blue     1               10001
green    2               10001
blue     2               10001
grey     3               10001

red      4               10002
green    5               10002
blue     5               10002

etc...

...并且我正在使用以下查询来生成有关该表的一些数据:

SELECT EventId as 'event', COUNT(DISTINCT MicrosoftId) as 'size',
SUM(CASE WHEN name = 'red' THEN 1 ELSE 0 END) as 'red',
SUM(CASE WHEN name = 'blue' THEN 1 ELSE 0 END) as 'blue',
SUM(CASE WHEN name = 'green' THEN 1 ELSE 0 END) as 'green'
FROM TagsMSCV 
WHERE name IN ('red','blue','green')
GROUP BY EventId

出问题的是我正在写的“大小”列。它应该是EventId中有多少唯一个MicrosoftId。因此,对于上面的示例,EventId 10001的大小应为3,EventId 10002的大小应为2。

我编写的SQL可以正常工作,但是COUNT(DISTINCT MicrosoftId)的大小全错了,我不知道为什么。我究竟做错了什么?

2 个答案:

答案 0 :(得分:2)

问题出在WHERE子句中,您的WHERE子句会过滤掉名称,因此count()将仅计算'red','blue','green'的已过滤名称。

因此,只需删除WHERE子句:

SELECT EventId as 'event', COUNT(DISTINCT MicrosoftId) as 'size',
       SUM(CASE WHEN name = 'red' THEN 1 ELSE 0 END) as 'red',
       SUM(CASE WHEN name = 'blue' THEN 1 ELSE 0 END) as 'blue',
       SUM(CASE WHEN name = 'green' THEN 1 ELSE 0 END) as 'green'
FROM TagsMSCV 
GROUP BY EventId;

答案 1 :(得分:2)

问题是您的WHERE子句。它会删除“红色”,“蓝色”和“绿色”以外的所有颜色,因此您无需计算其他颜色。 删除WHERE子句,您就可以了。

更新:您只想显示至少有一个红色,绿色或蓝色条目的事件。因此,添加一个HAVING子句或将您的查询放入子查询中才能使用WHERE。以下是一些选项:

具有单独的条件:

SELECT 
  EventId as event,
  COUNT(DISTINCT MicrosoftId) as size,
  SUM(CASE WHEN name = 'red' THEN 1 ELSE 0 END) as red,
  SUM(CASE WHEN name = 'blue' THEN 1 ELSE 0 END) as blue,
  SUM(CASE WHEN name = 'green' THEN 1 ELSE 0 END) as green
FROM TagsMSCV 
GROUP BY EventId
HAVING SUM(CASE WHEN name = 'red' THEN 1 ELSE 0 END) > 0
    OR SUM(CASE WHEN name = 'blue' THEN 1 ELSE 0 END) > 0 
    OR SUM(CASE WHEN name = 'green' THEN 1 ELSE 0 END) > 0 
ORDER BY event;

具有一个复合条件:

SELECT 
  EventId as event,
  COUNT(DISTINCT MicrosoftId) as size,
  SUM(CASE WHEN name = 'red' THEN 1 ELSE 0 END) as red,
  SUM(CASE WHEN name = 'blue' THEN 1 ELSE 0 END) as blue,
  SUM(CASE WHEN name = 'green' THEN 1 ELSE 0 END) as green
FROM TagsMSCV 
GROUP BY EventId
HAVING SUM(CASE WHEN name IN ('red', 'blue', 'green') THEN 1 ELSE 0 END) > 0
ORDER BY event;

在单独条件下的位置:

SELECT *
FROM
(
  SELECT 
    EventId as event,
    COUNT(DISTINCT MicrosoftId) as size,
    SUM(CASE WHEN name = 'red' THEN 1 ELSE 0 END) as red,
    SUM(CASE WHEN name = 'blue' THEN 1 ELSE 0 END) as blue,
    SUM(CASE WHEN name = 'green' THEN 1 ELSE 0 END) as green
  FROM TagsMSCV 
  GROUP BY EventId
) q
WHERE red > 0 OR blue > 0 OR green > 0
ORDER BY event;

在复合条件下:

SELECT *
FROM
(
  SELECT 
    EventId as event,
    COUNT(DISTINCT MicrosoftId) as size,
    SUM(CASE WHEN name = 'red' THEN 1 ELSE 0 END) as red,
    SUM(CASE WHEN name = 'blue' THEN 1 ELSE 0 END) as blue,
    SUM(CASE WHEN name = 'green' THEN 1 ELSE 0 END) as green
  FROM TagsMSCV 
  GROUP BY EventId
) q
WHERE red + blue + green > 0
ORDER BY event;