有没有办法找到分组数据的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
的所有列。
答
这是一个相当不可思议的方式!
SELECT GroupID, DateStamp, SomeName
FROM SomeTable ST1
WHERE X <
(SELECT COUNT(*)
FROM SomeTable ST2
WHERE ST1.GroupID=ST2.GroupID AND ST2.DateStamp > ST1.DateStamp)
编辑比尔的解决方案远远优于虽然。
如果这样起作用,它似乎是最好的,因为它是一个单一的查询。 – Justin 2010-06-01 22:24:54
非常感谢。我会在星期五上班时尝试一下,看看它是否有效。 – 2010-06-03 02:33:49
这似乎不起作用:“关键字'OVER'的语法不正确。”不过,我会继续尝试。 – 2010-06-04 13:43:17