【问题标题】:MySQL WITH ROLLUP when grouping by multiple fieldsMySQL WITH ROLLUP 按多个字段分组时
【发布时间】:2014-03-27 14:36:16
【问题描述】:

在按多个字段分组时执行 WITH ROLLUP,MySQL 会为每个组返回一个汇总行。 我对以下 dotable 中字段编号和 perc 的汇总感兴趣:

+------+---------------+--------+-------+--------+------------+
| RDT  | type          | number | total | perc   | thedate    |
+------+---------------+--------+-------+--------+------------+
| MAL  | checking      |    112 |  3249 | 3.4    | 2014-03-27 |
| MAL  | control       |     33 |  3249 | 1.0    | 2014-03-27 |
| MAL  | reconstructed |      5 |  3249 | 0.2    | 2014-03-27 |
| MAL  | regular       |    960 |  3249 | 29.5   | 2014-03-27 |
| MAL  | study         |     10 |  3249 | 0.3    | 2014-03-27 |
| tot  | NULL          |   1120 |  3249 | 34.0   | 2014-03-27 |

| PMC  | checking      |    107 |  3153 | 3.4    | 2014-03-27 |
| PMC  | control       |    167 |  3153 | 5.3    | 2014-03-27 |
| PMC  | reconstructed |      8 |  3153 | 0.3    | 2014-03-27 |
| PMC  | regular       |    833 |  3153 | 26.4   | 2014-03-27 |
| PMC  | study         |     72 |  3153 | 2.3    | 2014-03-27 |
| tot  | NULL          |   1187 |  3249 | 36.5   | 2014-03-27 |

| RAS  | checking      |      1 |   970 | 0.1    | 2014-03-27 |
| RAS  | control       |     42 |   970 | 4.3    | 2014-03-27 |
| RAS  | reconstructed |      1 |   970 | 0.1    | 2014-03-27 |
| RAS  | regular       |    318 |   970 | 32.8   | 2014-03-27 |
| RAS  | study         |      3 |   970 | 0.3    | 2014-03-27 |
| tot  | NULL          |    365 |   970 | 37.6   | 2014-03-27 |

| UOT  | checking      |     11 |  3527 | 0.3    | 2014-03-27 |
| UOT  | control       |    283 |  3527 | 8.0    | 2014-03-27 |
| UOT  | regular       |    235 |  3527 | 6.7    | 2014-03-27 |
| UOT  | study         |      8 |  3527 | 0.2    | 2014-03-27 |
| tot  | NULL          |    537 |  3527 | 15.2   | 2014-03-27 |
+------+---------------+--------+-------+--------+------------+

我尝试了这个查询:

mysql> SELECT
    IFNULL(`RDT`, 'tot') AS RDT,
    `type`,
    `number`,
    `total`,
    `perc`,
    `thedate`
FROM
    (
        SELECT
            `RDT`,
            `type`,
            `NUMBER`,
            `total`,
            `perc`,
            `THEDATE`
        FROM
            `dotable`
        GROUP BY
            RDT,
            `type`
        ORDER BY
            CASE
        WHEN RDT = 'UOT' THEN
            1
        END ASC
    ) AS X
GROUP BY
    X.RDT,
    X.`type` WITH ROLLUP;

但是输出错误,你能帮帮我吗? dotable 结构和行如下。

+------+---------------+--------+-------+--------+------------+
| RDT  | type          | number | total | perc   | thedate    |
+------+---------------+--------+-------+--------+------------+
| MAL  | checking      |    112 |  3249 | 3.4    | 2014-03-27 |
| MAL  | control       |     33 |  3249 | 1.0    | 2014-03-27 |
| MAL  | reconstructed |      5 |  3249 | 0.2    | 2014-03-27 |
| MAL  | regular       |    960 |  3249 | 29.5   | 2014-03-27 |
| MAL  | study         |     10 |  3249 | 0.3    | 2014-03-27 |
| MAL  | NULL          |     10 |  3249 | 0.3    | 2014-03-27 |
| PMC  | checking      |    107 |  3153 | 3.4    | 2014-03-27 |
| PMC  | control       |    167 |  3153 | 5.3    | 2014-03-27 |
| PMC  | reconstructed |      8 |  3153 | 0.3    | 2014-03-27 |
| PMC  | regular       |    833 |  3153 | 26.4   | 2014-03-27 |
| PMC  | study         |     72 |  3153 | 2.3    | 2014-03-27 |
| PMC  | NULL          |     72 |  3153 | 2.3    | 2014-03-27 |
| RAS  | checking      |      1 |   970 | 0.1    | 2014-03-27 |
| RAS  | control       |     42 |   970 | 4.3    | 2014-03-27 |
| RAS  | reconstructed |      1 |   970 | 0.1    | 2014-03-27 |
| RAS  | regular       |    318 |   970 | 32.8   | 2014-03-27 |
| RAS  | study         |      3 |   970 | 0.3    | 2014-03-27 |
| RAS  | NULL          |      3 |   970 | 0.3    | 2014-03-27 |
| UOT  | checking      |     11 |  3527 | 0.3    | 2014-03-27 |
| UOT  | control       |    283 |  3527 | 8.0    | 2014-03-27 |
| UOT  | regular       |    235 |  3527 | 6.7    | 2014-03-27 |
| UOT  | study         |      8 |  3527 | 0.2    | 2014-03-27 |
| UOT  | NULL          |      8 |  3527 | 0.2    | 2014-03-27 |
| tot  | NULL          |      8 |  3527 | 0.2    | 2014-03-27 |
+------+---------------+--------+-------+--------+------------+
24 rows in set

mysql> 

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for `dotable`
-- ----------------------------
DROP TABLE IF EXISTS `dotable`;
CREATE TABLE `dotable` (
  `RDT` varchar(10) DEFAULT NULL,
  `TYPE` varchar(50) DEFAULT NULL,
  `NUMBER` int(11) NOT NULL DEFAULT '0',
  `TOTAL` int(11) NOT NULL DEFAULT '0',
  `PERC` decimal(10,2) DEFAULT NULL,
  `THEDATE` date DEFAULT NULL,
  `ID` int(10) NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`ID`)
) ENGINE=MyISAM AUTO_INCREMENT=20 DEFAULT CHARSET=latin1;

-- ----------------------------
-- Records of dotable
-- ----------------------------
INSERT INTO `dotable` VALUES ('UOT', 'control', '283', '3527', '8.0', '2014-03-27', '1');
INSERT INTO `dotable` VALUES ('UOT', 'regular', '235', '3527', '6.7', '2014-03-27', '2');
INSERT INTO `dotable` VALUES ('UOT', 'study', '8', '3527', '0.2', '2014-03-27', '3');
INSERT INTO `dotable` VALUES ('UOT', 'checking', '11', '3527', '0.3', '2014-03-27', '4');
INSERT INTO `dotable` VALUES ('MAL', 'regular', '960', '3249', '29.5', '2014-03-27', '5');
INSERT INTO `dotable` VALUES ('MAL', 'study', '10', '3249', '0.3', '2014-03-27', '6');
INSERT INTO `dotable` VALUES ('MAL', 'control', '33', '3249', '1.0', '2014-03-27', '7');
INSERT INTO `dotable` VALUES ('MAL', 'reconstructed', '5', '3249', '0.2', '2014-03-27', '8');
INSERT INTO `dotable` VALUES ('MAL', 'checking', '112', '3249', '3.4', '2014-03-27', '9');
INSERT INTO `dotable` VALUES ('PMC', 'regular', '833', '3153', '26.4', '2014-03-27', '10');
INSERT INTO `dotable` VALUES ('PMC', 'study', '72', '3153', '2.3', '2014-03-27', '11');
INSERT INTO `dotable` VALUES ('PMC', 'control', '167', '3153', '5.3', '2014-03-27', '12');
INSERT INTO `dotable` VALUES ('PMC', 'checking', '107', '3153', '3.4', '2014-03-27', '13');
INSERT INTO `dotable` VALUES ('PMC', 'reconstructed', '8', '3153', '0.3', '2014-03-27', '14');
INSERT INTO `dotable` VALUES ('RAS', 'reconstructed', '1', '970', '0.1', '2014-03-27', '15');
INSERT INTO `dotable` VALUES ('RAS', 'regular', '318', '970', '32.8', '2014-03-27', '16');
INSERT INTO `dotable` VALUES ('RAS', 'study', '3', '970', '0.3', '2014-03-27', '17');
INSERT INTO `dotable` VALUES ('RAS', 'control', '42', '970', '4.3', '2014-03-27', '18');
INSERT INTO `dotable` VALUES ('RAS', 'checking', '1', '970', '0.1', '2014-03-27', '19');

【问题讨论】:

  • +1 用于发布准备通过复制和粘贴复制的数据。虽然不完全确定您想要什么……所以您在顶部显示的是您想要的最终结果? SQL 标准禁止你选择不属于分组的列——在 MySQL 严格模式下,这只会给你一个错误(就像在大多数其他 DBMS 中一样),在宽容模式下,它会给你一个随机的值 组内的行。
  • 不存储 '%'。需要一些常识!
  • 好吧,我修改了posttable。谢谢

标签: mysql rollup


【解决方案1】:

我对 dotable 中字段 number 和 perc 的汇总感兴趣

所以你需要做一个sum() 才能让它工作。

如果您不需要总总数,我们也可以将其删除。

对于版本

查询:

select 
    if(`type` is null, 'tot', `rdt`) as `rdt`,
    `type`,
    `number`,
    `total`,
    `perc`,
    `thedate`
from
    (select 
        `rdt`,
        `type`,
        sum(`number`) as `number`,
        `total`,
        sum(`perc`) as `perc`,
        `thedate`
    from
        `dotable`
    group by `rdt`, `type` with rollup) as t
where
    `rdt` is not null;

结果:

rdt |类型 |号码 |总计|聚碳酸酯 |日期 :-- | :------------ | -----: | ----: | ----: | :--------- 马尔 |检查 | 112 |第3249章3.40 | 2014-03-27 马尔 |控制 | 33 |第3249章1.00 | 2014-03-27 马尔 |重建| 5 |第3249章0.20 | 2014-03-27 马尔 |常规 | 960 |第3249章29.50 | 2014-03-27 马尔 |学习 | 10 |第3249章0.30 | 2014-03-27 总| | 1120 |第3249章34.40 | 2014-03-27 聚碳酸酯 |检查 | 107 |第3153章3.40 | 2014-03-27 聚碳酸酯 |控制 | 167 |第3153章5.30 | 2014-03-27 聚碳酸酯 |重建| 8 |第3153章0.30 | 2014-03-27 聚碳酸酯 |常规 |第833章第3153章26.40 | 2014-03-27 聚碳酸酯 |学习 | 72 |第3153章2.30 | 2014-03-27 总| |第1187章第3153章37.70 | 2014-03-27 RAS |检查 | 1 | 970 | 0.10 | 2014-03-27 RAS |控制 | 42 | 970 | 4.30 | 2014-03-27 RAS |重建| 1 | 970 | 0.10 | 2014-03-27 RAS |常规 | 318 | 970 | 32.80 | 2014-03-27 RAS |学习 | 3 | 970 | 0.30 | 2014-03-27 总| | 365 | 970 | 37.60 | 2014-03-27 UOT |检查 | 11 | 3527 | 0.30 | 2014-03-27 UOT |控制 | 283 | 3527 | 8.00 | 2014-03-27 UOT |常规 | 235 | 3527 | 6.70 | 2014-03-27 UOT |学习 | 8 | 3527 | 0.20 | 2014-03-27 总| |第537章3527 | 15.20 | 2014-03-27

对于版本 > 5.7

查询:

select 
    if(`type` is null, 'tot', `rdt`) as `rdt`,
    `type`,
    sum(`number`) as `number`,
    `total`,
    sum(`perc`) as `perc`,
    `thedate`
from
    `dotable`
group by `rdt`, `type` with rollup
having not grouping(rdt) <> 0;

结果:

rdt |类型 |号码 |总计|聚碳酸酯 |日期 :-- | :------------ | -----: | ----: | ----: | :--------- 马尔 |检查 | 112 |第3249章3.40 | 2014-03-27 马尔 |控制 | 33 |第3249章1.00 | 2014-03-27 马尔 |重建| 5 |第3249章0.20 | 2014-03-27 马尔 |常规 | 960 |第3249章29.50 | 2014-03-27 马尔 |学习 | 10 |第3249章0.30 | 2014-03-27 总| | 1120 |第3249章34.40 | 2014-03-27 聚碳酸酯 |检查 | 107 |第3153章3.40 | 2014-03-27 聚碳酸酯 |控制 | 167 |第3153章5.30 | 2014-03-27 聚碳酸酯 |重建| 8 |第3153章0.30 | 2014-03-27 聚碳酸酯 |常规 |第833章第3153章26.40 | 2014-03-27 聚碳酸酯 |学习 | 72 |第3153章2.30 | 2014-03-27 总| |第1187章第3153章37.70 | 2014-03-27 RAS |检查 | 1 | 970 | 0.10 | 2014-03-27 RAS |控制 | 42 | 970 | 4.30 | 2014-03-27 RAS |重建| 1 | 970 | 0.10 | 2014-03-27 RAS |常规 | 318 | 970 | 32.80 | 2014-03-27 RAS |学习 | 3 | 970 | 0.30 | 2014-03-27 总| | 365 | 970 | 37.60 | 2014-03-27 UOT |检查 | 11 | 3527 | 0.30 | 2014-03-27 UOT |控制 | 283 | 3527 | 8.00 | 2014-03-27 UOT |常规 | 235 | 3527 | 6.70 | 2014-03-27 UOT |学习 | 8 | 3527 | 0.20 | 2014-03-27 总| |第537章3527 | 15.20 | 2014-03-27

小提琴:
dbfiddle here

注意:在没有ERROR 1055的情况下使用group by时,您需要设置为

SET sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));

【讨论】:

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