使用 MAX() 选择未显示预期结果

Posted

技术标签:

【中文标题】使用 MAX() 选择未显示预期结果【英文标题】:select with MAX() not showing expected result 【发布时间】:2021-01-05 15:24:35 【问题描述】:

所以我有这张桌子。

 id     header_id   message_from           message         message_date            attachment
    1   0920-0001   USR-0920-0001   MESSAGE ID 1    18/09/2020 04:11    
    3   0920-0001   USR-0920-0001                   18/09/2020 11:15    862db13b42d569b4afe69828736f4ad8.jpg
    4   0920-0001   USR-0920-0001   MESSAGE ID 4    18/09/2020 11:16    
    5   0920-0001   ADMIN           MESSAGE ID 5    18/09/2020 11:16    
    6   0920-0001   ADMIN           MESSAGE ID 6    18/09/2020 11:16    
    7   0920-0002   USR-0920-0001     Hi            18/09/2020 11:52    

我想达到这个结果

    id  header_id   message_from    message         message_date      attachment
     6  0920-0001   ADMIN           MESSAGE ID 6    18/09/2020 11:16    
     7  0920-0002   USR-0920-0001   Hi              18/09/2020 11:52    

我正在尝试使用此查询

SELECT max(id) id , header_id,message from tbl_detail group by header_id

但是结果是这样的

id  header_id   message_from    message         message_date      attachment
 6  0920-0001   ADMIN           MESSAGE ID 1    18/09/2020 11:16    
 7  0920-0002   USR-0920-0001   Hi              18/09/2020 11:52    

我错过了什么吗?提前谢谢

【问题讨论】:

SELECT 语句中的列之间没有关系。 MAX(id) 的计算独立于 message。虽然MAX(id) 对于具有相同header_id(即一个组)的一组行是唯一的,但对于不同的行,消息具有不同的值。因此,您的查询不是有效的 SQL。 mysql 在 5.7.5 版本之前接受查询,但它保留自己为列 message 返回任何值的权利。 不能使用GROUP BY 选择行。 GROUP BY 计算 aggregate values 用于行组。它使用来自每个组的数据生成新行。在similar question 上查看this answer。另请阅读this answer 了解详细说明。 请学习如何使用GROUP BY 【参考方案1】:

您的查询一开始是无效的标准 SQL,因为 selectgroup by 子句不一致。 MySQL 可以容忍这种情况,但不会按照您的意愿行事(实际上您会为列 message 获得任意值)。

您想要header_id 的最新消息:不要想聚合 - 而是想过滤

select d.*
from tbl_detail d
where d.id = (select max(d1.id) from tbl_detail d1 where d1.header_id = d.header_id)

为了提高性能,请考虑在(header_id, id desc) 上建立索引。

如果您运行的是 MySQL 8.0,这也可以通过窗口函数来完成:

select d.*
from (
    select d.*, row_number() over(partition by header_id order by id desc) rn
    from tbl_detail d
) d
where rn = 1

根据您的实际要求,您可能希望使用列 message_date 而不是 id 来对行进行排序。

【讨论】:

以上是关于使用 MAX() 选择未显示预期结果的主要内容,如果未能解决你的问题,请参考以下文章

选择内部功能未按预期工作

如何在不显示所有结果的最大值的情况下为数学运算以及其他元素选择最大值

为啥选择查询在 mysql 集群中显示未排序的结果?

使用位置时页面布局未按预期显示:已修复页面内容

Mysql:使用左连接选择未按预期工作

VB 选择案例未按预期工作