Итоговые значения строк MySQL для каждого значения

#mysql #sql #count #sum #pivot

#mysql #sql #количество #сумма #сводная

Вопрос:

Структура таблицы MySQL, подобная этой:

 | id | company_id | project_id | status |
|  1 |          1 |          1 |  draft |
|  2 |          1 |          1 |   done |
|  3 |          1 |          1 |    wip |
|  4 |          1 |          2 |  draft |
  

Я хотел бы выполнить один запрос к таблице и получить такие результаты для одного company_id:

 | project_id | draft | wip | done | total |
|          1 |     1 |   1 |    1 |     3 |
|          2 |     1 |   0 |    0 |     1 |
  

В таблице может быть >.5M строк

Ответ №1:

Используйте условную агрегацию:

 select project_id, 
    sum(status = 'draft') draft,
    sum(status = 'wip') wip,
    sum(status = 'done') done,
    count(*) total
from mytable
group by project_id
  

Ответ №2:

Вы можете четко выбрать все status случаи, а затем выполнить динамический поворот, чтобы иметь все status значения, даже если недавно вставленные значения отличаются от текущих :

 SET @sql = NULL;

SELECT GROUP_CONCAT(
             CONCAT(
                    'SUM( status =''', status, ''' ) AS ',status
                    )
       )
  INTO @sql
  FROM ( SELECT DISTINCT status
           FROM t 
       ) t;

SET @sql = CONCAT('SELECT company_id, project_id,',@sql,',COUNT(*) AS total'
                   ' FROM t
                    GROUP BY company_id, project_id'); 


PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
  

Demo