sql查询选择列值最大的所有行

qoefvg9y  于 2021-06-18  发布在  Mysql
关注(0)|答案(3)|浏览(317)
CREATE TABLE `user_activity` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `user_id` int(11) DEFAULT NULL,
  `type` enum('request','response') DEFAULT NULL,
  `data` longtext NOT NULL,
  `created_at` datetime DEFAULT NULL,
  `source` varchar(255) DEFAULT NULL,
  `task_name` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
);

我有这个data:-

现在我需要选择 user_id=527 哪里 created_at 值是最大值。所以我需要这张图的最后3行。
这是我写的query:-

SELECT * 
FROM   user_activity 
WHERE  user_id = 527 
       AND source = 'E1' 
       AND task_name IN ( 'GetReportTask', 'StopMonitoringUserTask' ) 
       AND created_at = (SELECT Max(created_at) 
                         FROM   user_activity 
                         WHERE  user_id = 527 
                                AND source = 'E1' 
                                AND task_name IN ( 'GetReportTask', 
                                                   'StopMonitoringUserTask' ));

这是非常低效的,因为我再次运行与内部查询完全相同的查询,只是它忽略了 created_at . 正确的方法是什么?

3j86kqsm

3j86kqsm1#

order by created\ U at desc并将查询限制为返回1行。

SELECT * 
FROM   user_activity 
WHERE  user_id = 527 
   AND source = 'E1' 
   AND task_name IN ( 'GetReportTask', 'StopMonitoringUserTask' ) 
ORDER BY created_at DESC
LIMIT 1;
exdqitrt

exdqitrt2#

我将使用相关子查询:

SELECT ua.* 
FROM user_activity ua
WHERE ua.user_id = 527 AND source = 'E1' AND
      ua.task_name IN ('GetReportTask', 'StopMonitoringUserTask' ) AND
      ua.created_at = (SELECT MAX(ua2.created_at) 
                       FROM user_activity ua2
                       WHERE ua2.user_id = ua.user_id AND 
                             ua2.source = ua.source AND
                             ua2.task_name IN ( 'GetReportTask', 'StopMonitoringUserTask' )
                      );

尽管这看起来效率很低,但您可以在上创建索引 user_activity(user_id, source, task_name, created_at) . 有了这个索引,查询应该有不错的性能。

yzuktlbb

yzuktlbb3#

我使用eversql并应用自己的更改来生成这个使用self的select查询-join:-

SELECT * 
FROM   user_activity AS ua1 
       LEFT JOIN user_activity AS ua2 
              ON ua2.user_id = ua1.user_id 
                 AND ua2.source = ua1.source 
                 AND ua2.task_name IN ( 'GetReportTask', 'StopMonitoringUserTask' ) 
                 AND ua1.created_at < ua2.created_at 
WHERE  ua1.user_id = 527 
       AND ua1.source = 'E1' 
       AND ua1.task_name IN ( 'GetReportTask', 'StopMonitoringUserTask' ) 
       AND ua2.created_at IS NULL;

但是,我注意到两个查询的响应时间是相似的。我试着用explain来识别任何性能差异;从我对其输出的理解来看,没有明显的区别,因为适当的索引已经到位。为了可读性和可维护性,我只使用嵌套查询。

相关问题