【发布时间】:2010-10-08 04:53:45
【问题描述】:
假设我有一个包含几亿行的表,看起来像这样:
memID | foo | bar | foobar
1 | blah | blah | blah
1 | blah | blah | blah
1 | blah | blah | blah
1 | blah | blah | blah
1 | blah | blah | blah
1 | blah | blah | blah
1 | blah | blah | blah
2 | blah | blah | blah
2 | blah | blah | blah
2 | blah | blah | blah
2 | blah | blah | blah
2 | blah | blah | blah
.
.
.
10001 | blah | blah | blah
10001 | blah | blah | blah
我需要一个查询,该查询将返回成员 ID 范围内每个 memID 的前 N 行。 例如,如果 N = 3 并且范围是 0-2 它应该返回
memID | foo | bar | foobar
1 | blah | blah | blah
1 | blah | blah | blah
1 | blah | blah | blah
2 | blah | blah | blah
2 | blah | blah | blah
2 | blah | blah | blah
我考虑了几种方法,首先创建一个巨大的
SELECT TOP (3) *
FROM table
WHERE memID = 0
UNION ALL
SELECT TOP (3) *
FROM table
WHERE memID = 1
.
.
.
在代码中查询。由于可能显而易见的原因,这并不是一个真正现实的选择。
第二种方法是创建一个临时表并循环遍历 memID 的范围,将每个 memID 的 TOP 3 插入到该临时表中。
WHILE @MemID < 10000 AND @MemID > 0
BEGIN
INSERT INTO tmp_Table
SELECT TOP (3) *
FROM table
WHERE memID = @MemID
SET @MemID = @MemID + 1
END
这可行,但我想知道是否有一个更优雅的单一查询解决方案我缺少。
Cadaeic 给了我一个无需修修补补的答案,但感谢所有建议分析的人,看来我需要认真阅读。
【问题讨论】:
-
定义“顶部”。您需要指定一些条件,以选择具有给定 id 的行。
-
已编辑以更清楚地表明 TOP 是一个函数。
-
有主键吗?这样会更容易。
-
@blogsdon:我不认为这就是 Joel 的意思。您根据什么标准判断哪一行是 in TOP 3,哪一行不是?顶部通常伴随着一个 ORDER BY 来定义顶部的内容。还是更像是“最多三个任意样本行”?
-
哦,我明白了,除了它们都需要具有相同的 memID 之外,没有其他标准。所以是的,您对“最多三个任意样本行”的描述是正确的。
标签: sql sql-server database optimization