2014-06-12 24 views
2

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 

我已经尝试这样做,它的伟大工程。

但是,我还需要检查最近的记录是否是组中的记录。我试着修改这个查询:

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混乱了查询。

有没有简单的方法来检查最新记录是否是只有组中的记录?一个简单的布尔值将会很好,或者组中的记录数量也可以工作。

编辑:我试图做到这一点的原因是,我正在写评论系统,我希望用户能够编辑评论。编辑评论时,我想显示一个显示编辑的链接,点击后,您可以进入显示编辑的页面(如在Facebook上,或者修订系统如何针对stackoverflow上的问题工作)。所以我需要得到每条评论的最新版本,以及一个让我知道评论是否有多个版本的指示器(所以我知道是否显示“已编辑”链接)。该解决方案需要高效,因为线程中可能会有数百条评论。

+1

这是最好的办法,曾几何时,但一个不相关的子查询可能要快得多。 – Strawberry

+0

@Strawberry你会怎么做呢? – Nate

+1

@Nate就像Vulcronos和Gary的答案 – Aquillo

回答

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这可能比我的解决方案更快。 – Aquillo

+0

你会如何将它转换成连接语法?我一直在尝试,但不能为我的生活弄清楚它与'max'在那里:-) – Nate

+0

哦,哇,大声笑,我只是尝试用JOIN替换m1后的逗号,显然这就是所有必须的完成了! (我试图以明显错误的方式重写它)。谢谢! – Nate

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说:“只要你给我纪录给定的名称那里没有更高id”。

第二个LEFT JOIN说“给记录给定的名称和更小的id”。由于可能有更多的记录,我已将它与DISTINCT一起使用。最后CASE WHEN THEN END决定是否有任何更小的id

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 
+0

哦,我刚刚注意到它和@Vulcronos是一样的 –

相关问题