Подсчет различных идентификаторов, сгруппированных по другому идентификатору, дает неправильный счет - PullRequest
0 голосов
/ 20 сентября 2018

У меня есть таблица базы данных 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

Бит, который идет не так, это столбец размера, который я делаю.Предполагается, что число уникальных MicrosoftId в EventId.Таким образом, для приведенного выше примера EventId 10001 должен иметь размер 3, а EventId 10002 должен иметь размер 2.

Написанный мною SQL работает без ошибок, но размер из COUNT (DISTINCT MicrosoftId)все неправильно и я не могу понять почему.Что я делаю неправильно?

Ответы [ 2 ]

0 голосов
/ 20 сентября 2018

Проблема в вашем предложении 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;
0 голосов
/ 20 сентября 2018

Проблема с предложением 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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...