SQL Query用WHERE子句选择一定数量的记录

时间:2014-02-25 19:50:23

标签: sql sql-server

假设我有一个如下所示的表:

ID | EntityType | Foo  | Bar
----------------------------
1  | Business   | test | test
2  | Family     | welp | testing
3  | Individual | hmm  | 100
4  | Family     | test | test
5  | Business   | welp | testing
6  | Individual | hmm  | 100

这个表相当大,EntityType列中有“Business”的随机(相当罕见)实例。

这样的查询
SELECT TOP 500 * FROM Records WHERE EntityType='Business' ORDER BY ID DESC

完美地抓住了第一套企业,现在我将如何向后翻页并获得符合我标准的前一组500条记录?

我理解我可以查看ID之间的记录,但不能保证ID会是什么,例如它不会只是前一个查询的最后一个ID减去500,因为Business EntityType很少见。

我也看了一些分页模型,但我不知道如何整合它们同时保持我的WHERE子句就是这样(只接受EntityType of Business)并保证500条记录(我用了一个“页面”返回500条记录,仅显示约18家企业,因为它们在返回的500条记录中。)

我感谢你对此事的任何帮助!

3 个答案:

答案 0 :(得分:2)

select * from ( 
  select top 500 * from (
    select top 1000 * FROM Records WHERE EntityType='Business' ORDER BY ID DESC 
  ) x
  order by id 
) y 
order by id desc 

最内层查询 - 占据前1000名,获得第2页和第1页结果

第二级查询 - 从第一个查询中获取第2页记录

最外层 - 重新排序结果

答案 1 :(得分:1)

我相信你所需要的是分页。在CodeGuru上有很多关于分页的文章(我认为之前曾提到过):

http://www.codeguru.com/csharp/.net/net_data/article.php/c19611/Paging-in-SQL-Server-2005.htm

我认为你会找到你需要的一切

答案 2 :(得分:1)

所以,我这样做与其他答案略有不同。我总是用最小行拉出最后500行的查询看起来像这样,需要一个rowcount。

请注意,在查询外部使用rowcount会使指数更容易推送SQL语法。我希望没有必要。

Declare @row_min as integer
Declare @row_count as integer
set @row_min = 500
SELECT @row_count = COUNT(*) FROM Records WHERE EntityType='Business' ;
WITH MyCTE AS 
(
    SELECT 
    ID, EntityType, Foo, Bar,
    ROW_NUMBER() OVER (ORDER BY TagId) AS 'RowNum'
       FROM Records
       WHERE EntityType='Business'
)

Select TOP 500 *, (Select Max(RowNum) From MyCTE) As RowMax
FROM MyCTE
WHERE EntityType='Business'
    AND
    RowNum > 
        Case sign(@row_count - 500 - @row_min)
        When -1 Then (@row_count - 500)
        ELSE @row_min
        end
    AND
        RowNum < 
            Case sign(@row_count - 500 - @row_min)
            When -1 Then (@row_count)
            ELSE @row_min + 500
            end

--Note : Debugging purposes.
    select sign(@row_count - 500 - @row_min), (@row_count - 500 - @row_min), @row_count, @row_min