根据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的问题)。所以我需要获得每条评论的最新修订版,以及一个告诉我是否有多个评论修订版的指标(所以我知道是否显示“已编辑”的链接)。解决方案需要高效,因为一个线程中可能有数百条注释。答案 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