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

时间:2014-06-12 17:49:51

标签: mysql sql

根据this answer,获得每组最新记录的最佳方式是这样的:

SELECT m1.*
FROM messages m1 
LEFT JOIN messages m2 ON (m1.name = m2.name AND m1.id < m2.id)
WHERE m2.id IS NULL

我试过这个并且效果很好。

但是,我还需要检查最新记录是否是该组中的 only 记录。我尝试将查询修改为:

SELECT m1.*, COUNT(m3.name)
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
WHERE m2.id IS NULL

但它只返回一行。

如果我删除了COUNT()声明,请留下我们:

SELECT m1.*
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
WHERE m2.id IS NULL

返回重复的行,显然额外的LEFT JOIN会使查询混乱。

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

编辑:我试图这样做的原因是我正在编写评论系统,我希望用户能够编辑评论。编辑评论时,我想显示一个显示已编辑的链接,当点击该链接时,会将您带到显示编辑的页面(例如在facebook上,或者修订系统如何处理有关stackoverflow的问题)。所以我需要获得每条评论的最新修订版,以及一个告诉我是否有多个评论修订版的指标(所以我知道是否显示“已编辑”的链接)。解决方案需要高效,因为一个线程中可能有数百条注释。

3 个答案:

答案 0 :(得分:3)

尝试:

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的基准进行基准测试,看看哪种情况更快。

答案 1 :(得分:1)

未经测试,但我想这样的事情可以做到:

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

首先LEFT JOIN + WHERE说&#34;只给我带有给定名字的记录,其中没有更高id&#34;。

第二个LEFT JOIN说&#34;给出具有给定名称和较小id&#34;的记录。由于可能有更多记录,我已将其与DISTINCT一起使用。最后CASE WHEN THEN END确定是否有任何较小的id

答案 2 :(得分:1)

会像你这样的工作

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