#mysql #sql #select #group-by #multiple-columns
#mysql #sql #выберите #группировка по #несколько столбцов
Вопрос:
У меня есть таблица:
date, number, flag1, flag2, flag3
2015, 10, 1, NULL, NULL
2015, 10, 1, NULL, NULL
2015, 10, 0, NULL, NULL
2015, 11, 1, NULL, NULL
2015, 11, NULL, 1, NULL
2015, 11, NULL, 0, NULL
2015, 12, NULL, NULL, 0
2016, 10, 1, NULL, NULL
2016, 11, 0, NULL, NULL
2016, 13, NULL, 1, NULL
2016, 13, NULL, NULL, 1
2016, 13, NULL, NULL, 1
2016, 13, NULL, NULL, 1
(NULL = 0)
Мне нужно получить группировку данных по дате:
date, flag1, flag2, flag3
2015, 2, 1 0
2016, 1, 1, 1
Подробнее:
Для каждой даты необходимо подсчитать количество флагов1, флаг2, флаг3, флаг которых = 1 и столько же
например, для flag1:
number = 10, flag1 = 1
number = 10, flag1 = 0
number = 10, flag1 = 1
number = 10, flag1 = 1
будет считаться = 1
number = 10, flag1 = 1
number = 10, flag1 = 0
number = 11, flag1 = 1
number = 11, flag1 = 1
будет считаться = 2
number = 10, flag1 = 0
number = 10, flag1 = 0
number = 11, flag1 = 1
number = 11, flag1 = 1
будет считаться = 1
A написал предупреждающий sql-код, но это сложно, медленно и т. Д
SELECT
date,
SUM(count1) AS count1,
SUM(count2) AS count2,
SUM(count3) AS count3
FROM
(
SELECT
date,
IF(SUM(flag1) <> 0, 1, 0) AS count1,
IF(SUM(flag2) <> 0, 1, 0) AS count2,
IF(SUM(flag3) <> 0, 1, 0) AS count3
FROM
table
-- WHERE
GROUP BY
number
) AS tmp
GROUP BY
date
ORDER BY
date;
Подскажите, можно ли упростить и ускорить код
Упрощенный
SELECT
date,
SUM(count1) AS count1,
SUM(count2) AS count2,
SUM(count3) AS count3
FROM
(
SELECT
date,
COUNT(DISTINCT(flag1)) AS count1,
COUNT(DISTINCT(flag2)) AS count2,
COUNT(DISTINCT(flag3)) AS count3
FROM
table
-- WHERE
GROUP BY
object_id
) AS tmp
GROUP BY
date
ORDER BY
date;
Комментарии:
1. Что, если есть четвертый флаг?
Ответ №1:
Вариант вашего исходного запроса:
SELECT `date`,
SUM(flag1=1) AS flag1,
SUM(flag2=1) AS flag2,
SUM(flag3=1) AS flag3
FROM (
SELECT `date`,
MAX(flag1) AS flag1,
MAX(flag2) AS flag2,
MAX(flag3) AS flag3
FROM mytable
GROUP BY `date`, number) AS t
GROUP BY `date`
ORDER BY `date`
Вы можете попробовать это и посмотреть, как это сравнивается с другим запросом.
Комментарии:
1. Упрощенный ВЫБОР даты, СУММЫ (count1) КАК count1, SUM(count2) КАК count2, СУММА (count3) КАК count3 ИЗ (ВЫБЕРИТЕ дату, COUNT(DISTINCT(флаг1)) КАК count1, COUNT(DISTINCT(флаг2)) КАК count2, COUNT(DISTINCT(флаг3)) КАК count3 ИЗ таблицы — ГДЕ ГРУППА ПО object_id ) КАК tmp ГРУППА ПО дате ПОРЯДОК ПО дате;
Ответ №2:
Я предлагаю вам реструктурировать вашу таблицу примерно так:
date, number, flag_no, flag_value
2015, 10, 1, 1
2015, 10, 1, 1
2015, 10, 1, 0
2015, 11, 1, 1
2016, 10, 1, 1
2016, 11, 1, 0
2015, 11, 2, 1
2015, 11, 2, 0
2016, 13, 2, 1
2015, 12, 3, 0
2016, 13, 3, 1
2016, 13, 3, 1
2016, 13, 3, 1