有没有办法找到分组数据的TOP X记录?

有没有办法找到分组数据的TOP X记录?

问题描述:

我用的Sybase 12.5服务器工作,我有一个表定义为这样:有没有办法找到分组数据的TOP X记录?

CREATE TABLE SomeTable(
    [GroupID] [int] NOT NULL, 
    [DateStamp] [datetime] NOT NULL, 
    [SomeName] varchar(100), 
    PRIMARY KEY CLUSTERED (GroupID,DateStamp) 
) 

我希望能够列出,每[组ID],只有[日期戳]最新的X记录。踢球者是X> 1,所以普通的旧MAX()不会削减它。我假设有一个奇妙的方法来做到这一点与游标和什么不,但我想知道是否有一个更简单的方法没有这些东西。

我知道我错过了一些明显的东西,我会为自己踢不出来,但是......我没有得到它。请帮忙。

有没有办法找到TOP X记录,但有分组数据?

根据联机手册,Sybase 12.5支持WINDOW函数和ROW_NUMBER(),尽管它们的语法与标准SQL略有不同。

尝试这样:

SELECT SP.* 
FROM (
    SELECT *, ROW_NUMBER() OVER (windowA ORDER BY [DateStamp] DESC) AS RowNum 
    FROM SomeTable 
    WINDOW windowA AS (PARTITION BY [GroupID]) 
) AS SP 
WHERE SP.RowNum <= 3 
ORDER BY RowNum DESC; 

我没有的Sybase的一个实例,所以我没有测试过这一点。我只是从文档中综合这个例子。


我犯了一个错误。我所看到的文档是Sybase SQL Anywhere 11.看起来,Sybase ASA根本不支持WINDOW子句,即使在最新版本中也是如此。

这是另一个可以完成同样事情的查询。您可以使用自连接将SomeTable的每一行匹配到具有相同GroupID和更高版本DateStamp的所有行。如果后面有三排或更少的排,那么我们有前三排之一。

SELECT s1.[GroupID], s1.[Foo], s1.[Bar], s1.[Baz] 
FROM SomeTable s1 
LEFT OUTER JOIN SomeTable s2 
    ON s1.[GroupID] = s2.[GroupID] AND s1.[DateStamp] < s2.[DateStamp] 
GROUP BY s1.[GroupID], s1.[Foo], s1.[Bar], s1.[Baz] 
HAVING COUNT(*) < 3 
ORDER BY s1.[DateStamp] DESC; 

请注意,您必须名单SELECT列表相同的列你GROUP BY子句中列出。基本上,您希望此查询返回的s1的所有列。

+0

如果这样起作用,它似乎是最好的,因为它是一个单一的查询。 – Justin 2010-06-01 22:24:54

+0

非常感谢。我会在星期五上班时尝试一下,看看它是否有效。 – 2010-06-03 02:33:49

+0

这似乎不起作用:“关键字'OVER'的语法不正确。”不过,我会继续尝试。 – 2010-06-04 13:43:17

这是一个相当不可思议的方式!

SELECT GroupID, DateStamp, SomeName 
FROM SomeTable ST1 
WHERE X < 
    (SELECT COUNT(*) 
    FROM SomeTable ST2 
    WHERE ST1.GroupID=ST2.GroupID AND ST2.DateStamp > ST1.DateStamp) 

编辑比尔的解决方案远远优于虽然。