我正在使用Sybase 12.5服务器,我有一个如下定义的表:
CREATE TABLE SomeTable(
[GroupID] [int] NOT NULL,
[DateStamp] [datetime] NOT NULL,
[SomeName] varchar(100),
PRIMARY KEY CLUSTERED (GroupID,DateStamp)
)
我希望能够按[GroupID]列出[DateStamp]中最新的X记录。踢球者是X> 1,所以普通的旧MAX()不会削减它。我假设有一个非常讨厌的方法用游标和什么不做,但我想知道是否有一个更简单的方法没有那些东西。
我知道我错过了一些显而易见的东西,我会因为没有得到它而踢我自己,但是......我没有得到它。请帮忙。
有没有办法找到TOP X记录,但是有分组数据?
答案 0 :(得分:3)
根据在线手册,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的实例,所以我没有测试过这个。我只是从文档中合成这个例子。
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
中的所有列。
答案 1 :(得分:1)
这是一种非常难以捉摸的方式!
SELECT GroupID, DateStamp, SomeName
FROM SomeTable ST1
WHERE X <
(SELECT COUNT(*)
FROM SomeTable ST2
WHERE ST1.GroupID=ST2.GroupID AND ST2.DateStamp > ST1.DateStamp)
编辑比尔的解决方案非常受欢迎。