MySql根据字段值查询uniq记录

时间:2017-01-31 18:02:56

标签: mysql subquery

我已设置闹钟数据,我想要的是获取最新的优秀闹钟,

    CREATE TABLE `alarm` (
  `alarmId` int(10) unsigned NOT NULL,
  `dT` time(6) DEFAULT NULL,
  `sevId` int(10) unsigned DEFAULT NULL,
  `alarmText` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

-- ----------------------------
-- Records of alarm
-- ----------------------------
INSERT INTO `alarm` VALUES ('1', '00:48:05.000000', '1', 'alarm 1');
INSERT INTO `alarm` VALUES ('1', '01:48:17.000000', '2', 'alarm 1');
INSERT INTO `alarm` VALUES ('1', '02:48:34.000000', '3', 'alarm 1');
INSERT INTO `alarm` VALUES ('2', '00:48:00.000000', '2', 'alarm 2');
INSERT INTO `alarm` VALUES ('2', '00:52:07.000000', '1', 'alarm 2');
INSERT INTO `alarm` VALUES ('3', '16:49:24.000000', '2', 'alarm 3');

显示没有sevId 3的最新警报(清除),到目前为止我尝试的是下面的,结果是好的,除了alarmId 2应该只返回1个警报,

SELECT
    *
FROM    alarm
WHERE
    alarmId NOT IN (        SELECT alarmId FROM alarm WHERE sevId = '3'
    )
    -> ;
+---------+-----------------+-------+-----------+
| alarmId | dT              | sevId | alarmText |
+---------+-----------------+-------+-----------+
|       2 | 00:48:00.000000 |     2 | alarm 2   |
|       2 | 00:52:07.000000 |     1 | alarm 2   |
|       3 | 16:49:24.000000 |     2 | alarm 3   |
+---------+-----------------+-------+-----------+

预期结果

+---------+-----------------+-------+-----------+
| alarmId | dT              | sevId | alarmText |
+---------+-----------------+-------+-----------+
|       2 | 00:52:07.000000 |     1 | alarm 2   |
|       3 | 16:49:24.000000 |     2 | alarm 3   |
+---------+-----------------+-------+-----------+

1 个答案:

答案 0 :(得分:1)

您可以尝试在子查询中查找dT的最大值,并将其与主表连接,以获得仅包含max dT的行。

SELECT 
    a.*
FROM
    alarm a
        INNER JOIN
    (SELECT 
        alarmId, MAX(dT) dT
    FROM
        alarm
    GROUP BY alarmId) b ON a.alarmId = b.alarmId AND a.dT = b.dT
WHERE
    a.alarmId NOT IN (SELECT 
            alarmId
        FROM
            alarm
        WHERE
            sevId = '3')

不使用group by因此更快的方法:

SELECT 
    a.*
FROM
    alarm a
        LEFT JOIN
    alarm b ON a.alarmId = b.alarmId AND a.dT < b.dT
WHERE
    b.alarmId IS NULL
        AND a.alarmId NOT IN (SELECT 
            alarmId
        FROM
            alarm
        WHERE
            sevId = '3')