Многократный подсчет Mysql в одном запросе

Как я могу подсчитать записи для двух столбцов в одной таблице, используя разные критерии запроса?

Таблица выглядит так:

   user_id  |   date     | status
------------------------------
      1     | 2011-01-02 |   1
      2     | 2011-01-03 |   1
      3     | 2011-01-02 |   0
      4     | 2011-01-03 |   1
      1     | 2011-01-02 |   1

Я хочу подсчитать два значения в одном запросе. Первый — это номер группы user_id по статусу, а второй — количество групп user_id по дате.

Как я могу это сделать?


person Sergio    schedule 19.03.2011    source источник
comment
используйте что-то вроде SELECT COUNT...   -  person Neigyl R. Noval    schedule 19.03.2011
comment
Пожалуйста, приведите пример ожидаемого результата, потому что количество на статус не имеет отношения к количеству на дату. Декартово произведение является единственным результатом.   -  person OMG Ponies    schedule 19.03.2011


Ответы (2)


У вас не может быть разных предложений GROUP BY в одном и том же запросе — каждый счет должен быть в независимом запросе.

Но вы можете вернуть вывод в одном запросе/наборе результатов, используя подзапросы (подзапрос в предложении SELECT):

   SELECT COUNT(a.user_id) AS numUsersPerStatus,
          (SELECT COUNT(b.user_id)
             FROM YOUR_TABLE b
         GROUP BY b.date) AS numUsersPerDate
    FROM YOUR_TABLE a
GROUP BY a.status
person OMG Ponies    schedule 19.03.2011
comment
Если в разделе «Выбор столбца» используется подзапрос, он должен возвращать только 1 строку и 1 столбец, numUsersPerDate будет возвращать несколько строк для разных дат? я думаю, что этот запрос может дать ошибку времени выполнения на основе данных? пожалуйста, поправьте меня, если я ошибаюсь..... - person Nitin Midha; 19.03.2011
comment
@Nitin Midha: Нет, это не приведет к ошибке выполнения. numUsersPerDate будет дублироваться для каждого счетчика статуса — результатом будет декартово произведение. - person OMG Ponies; 19.03.2011
comment
Тогда я надеюсь, что это должно быть в предложении from с перекрестным соединением .... Это какая-то известная разница между SQL Server и MySQL? Насколько я помню, в SQL Server выдает ошибку... - person Nitin Midha; 19.03.2011
comment
@Nitin Midha: CROSS JOIN - это просто синтаксис ANSI-92 для создания декартова произведения. И нет, предоставленный запрос также не выдаст ошибку на SQL Server — подзапросы очень распространены, потому что ANSI-89 не поддерживает ВНЕШНЕЕ соединение (этот пример был бы переписан с левым соединением, если бы были критерии для связывания столы). - person OMG Ponies; 19.03.2011

Вы нет.

Вы должны использовать два запроса. Нет никакого преимущества в том, чтобы делать это с помощью одного запроса.

Если вы действительно хотите это сделать, попробуйте следующее:

SELECT 'date' AS grptype, date AS grp, COUNT(DISTINCT user_id) AS cnt
FROM yourtable
GROUP BY date
UNION ALL
SELECT 'status' AS grptype, status AS grp, COUNT(DISTINCT user_id) AS cnt
FROM yourtable
GROUP BY status

Результат:

grptype    grp         cnt
date       2011-01-02  2  
date       2011-01-03  2  
status     0           1  
status     1           3  

Однако я бы настоятельно не советовал бы этого делать. Вам нужны два разных и несвязанных набора результатов, поэтому вы должны использовать два отдельных запроса.

person Mark Byers    schedule 19.03.2011
comment
UNION как есть не будет работать — столбцы даты и состояния представляют собой разные типы данных. И вы хотели бы использовать это как производное табличное/встроенное представление, чтобы в конечном итоге использовать MAX для сжатия в меньшее количество строк. - person OMG Ponies; 19.03.2011
comment
почему вы не советуете этого делать? - person doc_id; 19.03.2011
comment
@rahmanisback: Потому что это злоупотребление SQL. Каждый раз, когда вы смешиваете типы данных в одном столбце, умирает единорог. В большинстве баз данных такие вещи даже не разрешены. MySQL позволяет это из-за преобразования типов. Но только потому, что вы можете, не означает, что вы должны. - person Mark Byers; 19.03.2011