Mysql 如何获取每组中的最新记录并检查它是否是唯一的记录?

Mysql 如何获取每组中的最新记录并检查它是否是唯一的记录?,mysql,sql,Mysql,Sql,据了解,获得每组最新记录的最佳方法如下: SELECT m1.* FROM messages m1 LEFT JOIN messages m2 ON (m1.name = m2.name AND m1.id < m2.id) WHERE m2.id IS NULL 返回重复的行,因此显然,额外的左连接会打乱查询 是否有一种简单的方法来检查返回的最新记录是否是组中的唯一记录?一个简单的bool值就可以了,或者组中的记录数也可以 编辑:我之所以尝试这样做,是因为我正在编写一个评论系统,我希

据了解,获得每组最新记录的最佳方法如下:

SELECT m1.*
FROM messages m1 
LEFT JOIN messages m2 ON (m1.name = m2.name AND m1.id < m2.id)
WHERE m2.id IS NULL
返回重复的行,因此显然,额外的左连接会打乱查询

是否有一种简单的方法来检查返回的最新记录是否是组中的唯一记录?一个简单的bool值就可以了,或者组中的记录数也可以


编辑:我之所以尝试这样做,是因为我正在编写一个评论系统,我希望用户能够编辑评论。编辑评论时,我想显示一个链接,显示编辑过的评论,单击该链接后,会将您带到一个页面,显示facebook上的编辑,或修订系统如何处理stackoverflow上的问题。因此,我需要获得每个评论的最新版本,以及一个指示器,让我知道评论是否有多个版本,以便我知道是否显示编辑的链接。解决方案需要高效,因为一个线程中可能有数百条注释。

未经测试,但我想这样做可以:

SELECT DISTINCT m1.*
, CASE 
    WHEN m3.id IS NULL 
    THEN 'only record with this name' 
    ELSE 'not only record with this name' 
    END
FROM messages m1 
LEFT JOIN messages m2 ON (m1.name = m2.name AND m1.id < m2.id)
LEFT JOIN messages m3 ON (m1.name = m3.name AND m1.id > m3.id)
WHERE m2.id IS NULL
First LEFT JOIN+其中说只给我没有更高id的具有给定名称的记录

左二JOIN表示为记录提供一个给定的名称和一个较小的id。因为可能会有更多的记录,所以我将其与DISTINCT一起使用。最后一个CASE WHEN THEN END确定是否有更小的id。

尝试:

SELECT m1.*, m2.total
FROM messages m1,
(select max(id) id, count(*) total, name
 from messages
 group by name) m2
where m1.name = m2.name and m1.id = m2.id

如果需要,可以将其转换为联接语法,但其思想是运行子查询并联接一次,而不是两次,并且只使用相等联接,这可以提高性能。我将对我的解决方案和Aquillo的解决方案进行基准测试,看看哪一个在您的情况下更快。

是否希望这项工作适合您

with cteMessages  as 

(select Name, max(Id) as LatestId, count(Id) as CountIds
from [Messages]
group by Name)

select * 
from  cteMessages as c
    inner join [Messages] as m 
        on c.Name = m.Name
        and c.LatestId = r.Id

哦,我刚刚注意到它与@Vulcronost的方法相同,这曾经是最好的方法,但不相关的子查询可能会快得多。@草莓你会怎么做?@Nate就像Vulcronos和GaryYes的答案一样,就像Vulcronos的答案一样——除了我用正确的连接语法编写它之外,您如何将其转换为连接语法?我一直在尝试,但我一辈子都无法用最大值来解决这个问题:-哦,哇,哈哈,我只是试着用JOIN替换m1后面的逗号,显然这就是我要做的一切!我试图用一种明显错误的方式重写它。谢谢
SELECT m1.*, m2.total
FROM messages m1,
(select max(id) id, count(*) total, name
 from messages
 group by name) m2
where m1.name = m2.name and m1.id = m2.id
with cteMessages  as 

(select Name, max(Id) as LatestId, count(Id) as CountIds
from [Messages]
group by Name)

select * 
from  cteMessages as c
    inner join [Messages] as m 
        on c.Name = m.Name
        and c.LatestId = r.Id