在mysql中使用group by选择最小值
Posted
技术标签:
【中文标题】在mysql中使用group by选择最小值【英文标题】:Select minimum value with group by in mysql 【发布时间】:2013-03-26 05:12:19 【问题描述】:我的数据库方案,
CREATE TABLE `result` (
`ID` bigint(21) NOT NULL AUTO_INCREMENT,
`datetime` datetime DEFAULT NULL,
`recordnum` int(11) DEFAULT NULL,
`recordtype` int(11) DEFAULT NULL,
`minvalue` int(11) DEFAULT NULL,
`maxvalue` int(11) DEFAULT NULL,
`data1` int(11) DEFAULT NULL,
`data2` int(11) DEFAULT NULL,
`area` varchar(32) DEFAULT NULL,
PRIMARY KEY (`ID`),
UNIQUE KEY `res` (`datetime`,`recordnum`,`area`)
) ENGINE=MyISAM AUTO_INCREMENT=7 DEFAULT CHARSET=latin1;
数据样本
INSERT INTO `result` VALUES ('1', '2013-03-26 12:03:31', '2', '1', '5', '10', '100', '200','Zone1'); INSERT INTO `result` VALUES ('2', '2013-03-26 12:03:31', '2', '1', '2', '7', '20', '20','Zone2'); INSERT INTO `result` VALUES ('3', '2013-03-26 12:03:31', '5', '2', '1', '2', '8', '15','Zone2'); INSERT INTO `result` VALUES ('4', '2013-03-26 12:00:31', '2', '1', '2', '7', '100', '200','Zone1'); INSERT INTO `result` VALUES ('5', '2013-03-26 12:00:31', '2', '1', '3', '9', '100', '200','Zone2'); INSERT INTO `result` VALUES ('6', '2013-03-26 12:00:31', '5', '2', '7', '2', '4', '10', 'Zone2'); INSERT INTO `result` VALUES ('7', '2013-03-25 12:03:31', '2', '1', '5', '10', '100', '200','Zone1'); INSERT INTO `result` VALUES ('8', '2013-03-25 12:03:31', '2', '1', '2', '7', '20', '20','Zone2'); INSERT INTO `result` VALUES ('9', '2013-03-25 12:03:31', '5', '2', '1', '2', '8', '15','Zone2'); INSERT INTO `result` VALUES ('10', '2013-03-25 12:00:31', '2', '1', '2', '7', '100', '200','Zone1'); INSERT INTO `result` VALUES ('11', '2013-03-25 12:00:31', '2', '1', '3', '9', '100', '200','Zone2'); INSERT INTO `result` VALUES ('12', '2013-03-25 12:00:31', '5', '2', '7', '2', '4', '10','Zone2'); INSERT INTO `result` VALUES ('13', '2013-03-25 11:03:31', '2', '1', '3', '10', '100','200', 'Zone1'); INSERT INTO `result` VALUES ('14', '2013-03-25 11:03:31', '2', '1', '8', '7', '20', '20','Zone2'); INSERT INTO `result` VALUES ('15', '2013-03-25 11:03:31', '5', '2', '2', '2', '8', '15','Zone2'); INSERT INTO `result` VALUES ('16', '2013-03-25 11:00:31', '2', '1', '1', '7', '100', '200','Zone1'); INSERT INTO `result` VALUES ('17', '2013-03-25 11:00:31', '2', '1', '9', '9', '100', '200','Zone2'); INSERT INTO `result` VALUES ('18', '2013-03-25 11:00:31', '5', '2', '12', '2', '4', '10','Zone2');
我想要的是在每个 recordnum 和 area 以及 date
的最小值为最小值时查询每个值 +----+---------------------+-----------+-------+----------+----------+-------+-------+------------+
| ID | datetime | recordnum | area |minvalue | maxvalue | data1 | data2 | recordtype |
+----+---------------------+-----------+-------+----------+----------+-------+-------+------------+
| 2 | 2013-03-26 12:03:31 | 2 | Zone2 | 2 | 7 | 20 | 20 | 1 |
| 3 | 2013-03-26 12:03:31 | 5 | Zone2 | 1 | 2 | 8 | 15 | 2 |
| 4 | 2013-03-26 12:00:31 | 2 | Zone1 | 2 | 7 | 100 | 200 | 1 |
| 8 | 2013-03-25 12:03:31 | 2 | Zone2 | 2 | 7 | 20 | 20 | 1 |
| 9 | 2013-03-25 12:03:31 | 5 | Zone2 | 1 | 2 | 8 | 15 | 2 |
| 16 | 2013-03-25 11:00:31 | 2 | Zone1 | 1 | 7 | 100 | 200 | 1 |
+----+---------------------+-----------+-------+----------+----------+-------+-------+------------+
下面这个查询结果很好,但仍然显示重复记录,请帮助
SELECT a.*
FROM result a
JOIN
(
SELECT datetime as mindatetime,DATE(datetime) dateOnly,area, recordNum, MIN(minvalue) min_val
FROM result
GROUP BY dateOnly,area, recordNum
) b ON a.area = b.area AND
a.recordNUM = b.recordNum AND
a.minvalue = b.min_val ;
+----+---------------------+-----------+------------+----------+----------+-------+-------+-------+
| ID | datetime | recordnum | recordtype | minvalue | maxvalue | data1 | data2 | area |
+----+---------------------+-----------+------------+----------+----------+-------+-------+-------+
| 2 | 2013-03-26 12:03:31 | 2 | 1 | 2 | 7 | 20 | 20 | Zone2 |
| 2 | 2013-03-26 12:03:31 | 2 | 1 | 2 | 7 | 20 | 20 | Zone2 |
| 3 | 2013-03-26 12:03:31 | 5 | 2 | 1 | 2 | 8 | 15 | Zone2 |
| 3 | 2013-03-26 12:03:31 | 5 | 2 | 1 | 2 | 8 | 15 | Zone2 |
| 4 | 2013-03-26 12:00:31 | 2 | 1 | 2 | 7 | 100 | 200 | Zone1 |
| 8 | 2013-03-25 12:03:31 | 2 | 1 | 2 | 7 | 20 | 20 | Zone2 |
| 8 | 2013-03-25 12:03:31 | 2 | 1 | 2 | 7 | 20 | 20 | Zone2 |
| 9 | 2013-03-25 12:03:31 | 5 | 2 | 1 | 2 | 8 | 15 | Zone2 |
| 9 | 2013-03-25 12:03:31 | 5 | 2 | 1 | 2 | 8 | 15 | Zone2 |
| 10 | 2013-03-25 12:00:31 | 2 | 1 | 2 | 7 | 100 | 200 | Zone1 |
| 16 | 2013-03-25 11:00:31 | 2 | 1 | 1 | 7 | 100 | 200 | Zone1 |
+----+---------------------+-----------+------------+----------+----------+-------+-------+-------+
【问题讨论】:
Get top n records for each group of grouped results 的可能重复项 【参考方案1】:如何解决这个问题有很多变化。一种是使用单独的子查询,它为每个area and recordNum
获取最小值minvalue
。然后将子查询的结果重新连接到原始表中,以便您可以获取行中的所有列。
SELECT a.*
FROM result a
INNER JOIN
(
SELECT area, recordNum, MIN(minvalue) min_val
FROM result
GROUP BY area, recordNum
) b ON a.area = b.area AND
a.recordNUM = b.recordNum AND
a.minvalue = b.min_val
SQLFiddle Demo
输出
╔════╦══════════════════════════════╦═══════════╦════════════╦══════════╦══════════╦═══════╦═══════╦═══════╗
║ ID ║ DATETIME ║ RECORDNUM ║ RECORDTYPE ║ MINVALUE ║ MAXVALUE ║ DATA1 ║ DATA2 ║ AREA ║
╠════╬══════════════════════════════╬═══════════╬════════════╬══════════╬══════════╬═══════╬═══════╬═══════╣
║ 2 ║ March, 26 2013 12:03:31+0000 ║ 2 ║ 1 ║ 2 ║ 7 ║ 20 ║ 20 ║ Zone2 ║
║ 3 ║ March, 26 2013 12:03:31+0000 ║ 5 ║ 2 ║ 1 ║ 2 ║ 8 ║ 15 ║ Zone2 ║
║ 4 ║ March, 26 2013 12:00:31+0000 ║ 2 ║ 1 ║ 2 ║ 7 ║ 100 ║ 200 ║ Zone1 ║
╚════╩══════════════════════════════╩═══════════╩════════════╩══════════╩══════════╩═══════╩═══════╩═══════╝
【讨论】:
谢谢,查询工作完美,我还有一个问题如何在一天添加组基数,我添加了group by DATE_FORMAT(DATETIME,'%Y-%m-%d')
所以我想要 MINVALUE 一天但它不起作用,谢谢 in adv。
这里的结果缺少什么?你想格式化日期吗?为什么需要在 group by 子句中添加它??
不,查询结果有效,我想知道如何获取每日的最小值。
我只是更新了顶部问题的数据样本,也是预期的结果,当 MINVALUE 记录最小时,只有 1 个基于组合 date 、 recordnum 和 area 的唯一记录。
现在我得到了结果但仍然需要删除重复记录,有什么建议吗?以上是关于在mysql中使用group by选择最小值的主要内容,如果未能解决你的问题,请参考以下文章
MySQL进阶5--分组排序和分组查询 group by(having) /order by
SQL Server报错:选择列表中的列无效,因为该列没有包含在聚合函数或 GROUP BY 子句中
聚合函数以及MYSQL分组查询——GROUP BY语句(一天一个小技巧,明天你就是专业人士,欧耶!)