【问题标题】:mysql: simplify request - grouping by multi fieldsmysql:简化请求 - 按多字段分组
【发布时间】:2016-10-18 12:39:17
【问题描述】:

我有一张桌子:

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,都需要统计flag = 1的flag1flag2flag3的数量和相同的号码

例如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;  

【问题讨论】:

  • 如果有第四个标志怎么办?

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


【解决方案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

【讨论】:

  • 简化 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】:

我建议您将表格重组为:

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

【讨论】:

    猜你喜欢
    • 2014-11-05
    • 1970-01-01
    • 2013-11-08
    • 2011-08-01
    • 2012-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-28
    相关资源
    最近更新 更多