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

时间:2016-10-18 12:39:17

标签: mysql sql select group-by multiple-columns

我有一张桌子:

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

详情:

对于每个日期,需要计算 flag1 flag2 flag3 的数量,其标志= 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

写了一个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;  

2 个答案:

答案 0 :(得分:0)

我建议你将表重组为:

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

答案 1 :(得分:0)

原始查询的变体:

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