Несколько значений для определенных значений в одном столбце с группировкой по - PullRequest
0 голосов
/ 10 февраля 2020

У меня есть таблица событий, в которой работают разные учетные записи. Нам нужно подсчитать определенные типы событий по счетам.

Ввод:

| accountId | eventType |
|-----------|-----------|
| 1         | start     |
| 1         | stop      |
| 1         | start     |
| 1         | start     |
| 2         | start     |
| 2         | start     |

Запрос:

select accountId, count(eventType='start') as starts, count(eventType='stop') as stops FROM eventTable GROUP BY accountId

Ожидаемый результат:

| accountId | starts    | stops     |
|-----------|-----------|-----------|
| 1         | 3         | 1         |
| 2         | 2         | 0         |

Кажется, он просто пытается присвоить значение и считает то же самое для всех значений - что не предназначено. Можно было бы обойти использование

sum(case when eventType='start' then 1 alse 0) as starts

, но есть ли лучший (более чистый) способ непосредственного использования счетчиков?

Правка: я использую Афину, поэтому синтаксис и поведение HIVE / Presto предпочтительнее.

1 Ответ

1 голос
/ 10 февраля 2020

В вашем запросе отсутствует предложение from, но я предполагаю, что это опечатка.

Обратите внимание:

select 
    accountId, 
    sum(eventType = 'start') as starts, 
    sum(eventType = 'stop') as stops 
from ???
GROUP BY accountId

Обоснование: count() учитывает все значения, которые не являются null. С другой стороны, если | eventType не равно null, условие внутри count() возвращает логическое значение или значение 0/1 - в зависимости от вашей базы данных. Вам нужно sum() эти 0/1 значения.

Обратите внимание, что приведенный выше синтаксис поддерживается только в MySQL. Если вы используете Postgres (это другая база данных, в которой будет выполняться ваш исходный код), в этом нет необходимости, вместо этого можно использовать предложение filer:

select 
    accountId, 
    count(*) filter(where eventType = 'start') as starts, 
    count(*) filter(where eventType = 'stop') as stops 
from ???
GROUP BY accountId
...