我想在一个查询中返回每个部分的前10条记录。有人能帮我做吗?Section是表中的列之一。
数据库为SQL Server 2005。我想按输入的日期返回前10名。部分包括业务、本地和特性。对于一个特定的日期,我只想要顶部(10)业务行(最近的条目)、顶部(10)本地行和顶部(10)特性。
我想在一个查询中返回每个部分的前10条记录。有人能帮我做吗?Section是表中的列之一。
数据库为SQL Server 2005。我想按输入的日期返回前10名。部分包括业务、本地和特性。对于一个特定的日期,我只想要顶部(10)业务行(最近的条目)、顶部(10)本地行和顶部(10)特性。
当前回答
尝试了下面的方法,它也适用于领带。
SELECT rs.Field1,rs.Field2
FROM (
SELECT Field1,Field2, ROW_NUMBER()
OVER (Partition BY Section
ORDER BY RankCriteria DESC ) AS Rank
FROM table
) rs WHERE Rank <= 10
其他回答
如果你知道这些部分是什么,你可以这样做:
select top 10 * from table where section=1
union
select top 10 * from table where section=2
union
select top 10 * from table where section=3
这适用于SQL Server 2005(编辑以反映您的澄清):
select *
from Things t
where t.ThingID in (
select top 10 ThingID
from Things tt
where tt.Section = t.Section and tt.ThingDate = @Date
order by tt.DateEntered desc
)
and t.ThingDate = @Date
order by Section, DateEntered desc
虽然这个问题是关于SQL Server 2005的,但大多数人已经继续前进了,如果他们确实发现了这个问题,在其他情况下首选的答案可能是使用CROSS APPLY,就像这篇博客文章中所说明的那样。
SELECT *
FROM t
CROSS APPLY (
SELECT TOP 10 u.*
FROM u
WHERE u.t_id = t.t_id
ORDER BY u.something DESC
) u
该查询涉及两个表。OP的查询只涉及1个表,在这种情况下,基于窗口函数的解决方案可能更有效。
UNION操作符对您有用吗?每个部分有一个SELECT,然后将它们联合在一起。不过,我猜它只适用于固定数量的部分。
如果我们使用SQL Server >= 2005,那么我们可以只用一个选择来解决任务:
declare @t table (
Id int ,
Section int,
Moment date
);
insert into @t values
( 1 , 1 , '2014-01-01'),
( 2 , 1 , '2014-01-02'),
( 3 , 1 , '2014-01-03'),
( 4 , 1 , '2014-01-04'),
( 5 , 1 , '2014-01-05'),
( 6 , 2 , '2014-02-06'),
( 7 , 2 , '2014-02-07'),
( 8 , 2 , '2014-02-08'),
( 9 , 2 , '2014-02-09'),
( 10 , 2 , '2014-02-10'),
( 11 , 3 , '2014-03-11'),
( 12 , 3 , '2014-03-12'),
( 13 , 3 , '2014-03-13'),
( 14 , 3 , '2014-03-14'),
( 15 , 3 , '2014-03-15');
-- TWO earliest records in each Section
select top 1 with ties
Id, Section, Moment
from
@t
order by
case
when row_number() over(partition by Section order by Moment) <= 2
then 0
else 1
end;
-- THREE earliest records in each Section
select top 1 with ties
Id, Section, Moment
from
@t
order by
case
when row_number() over(partition by Section order by Moment) <= 3
then 0
else 1
end;
-- three LATEST records in each Section
select top 1 with ties
Id, Section, Moment
from
@t
order by
case
when row_number() over(partition by Section order by Moment desc) <= 3
then 0
else 1
end;