mysql: 简化请求 - 按多字段分组

mysql: simplify request - grouping by multi fields

我有一个 table:

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

详情:

对于每个date需要统计flag1,flag2,flag3 flag = 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写了warking 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;  

我建议您将 table 重组为:

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

原始查询的变体:

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`

您可以尝试一下,看看它与其他查询相比如何。

Demo here