SQL在每个SELECT请求上获得ROW_NUMBER和COUNT

时间:2014-07-24 18:02:19

标签: mysql sql-server oracle11g aggregate-functions row-number

我正在构建一个网格机制,我需要从数据库中检索找到的总数或记录数,只检索一系列带有row_number的记录。

我正在使用SqlServer进行测试,但我也需要在Oracle和MySql上支持它。

这就是我的尝试,但我无法让它发挥作用:

    SELECT * FROM 
           (SELECT ROW_NUMBER() AS RN, 
                   COUNT(*) AS TOTALCN, 
                   Id, 
                   Name, 
                   Phone 
            FROM MyTable WHERE Deleted='F')
            WHERE RN > 100 AND RN < 150;

这个想法是:

MyTable -> number of records: 1000
Select Id, Name, Phone from MyTable where Deleted='F' -> number of records: 850
Get the records 100 to 150 from the 850.

我希望得到一个像:

RN   TOTALCN Id    Name   Phone
1    850     Data  Data   Data
2    850     Data  Data   Data
3    850     Data  Data   Data
4    850     Data  Data   Data
5    850     Data  Data   Data
6    850     Data  Data   Data

CN (850)将是我的网格总记录数。 RN将是数据的网格索引。

有人帮我完成了吗?

感谢您的帮助。

[编辑]

所以,我会在每个SELECT上添加一个ORDER BY。这是我到目前为止所得到的:

SELECT * FROM (SELECT ROW_NUMBER() 
              OVER (ORDER BY ID)  AS RN, 
              COUNT(*) OVER (ORDER BY (SELECT NULL) AS CNT) 
              Id, Name Phone FROM MyTable WHERE Deleted='F') 
T WHERE RN > 100 AND RN < 500;

我会走正路吗?

SQL会有多贵?

2 个答案:

答案 0 :(得分:2)

这可能意味着允许分页。显示总行数可能非常昂贵。

我发现在各种数据库中运行良好的一种方法是将工作分为两部分。首先,您在临时表中收集相关行的ID。其次,您查询完整数据集。第一部分中收集的数据为您提供了一种计算特定页面上行总数和行ID的简便方法。

这是SQL Server的一个粗略示例。请注意,该示例不依赖于row_number()等窗口函数,这些函数在MySQL中不可用。

create table #id_list (rn int identity, pk int);

insert   #id_list
         (pk)
select   customer_id
from     customers
where    name like '%Joe%';

select   (select  count(*) from #id_list) as total_rows
,        rn -- The row's number
,        name
,        birth_date
,        ... -- Other columns
from     #id_list id
join     customer c
on       c.pk = c.customer_id
where    rn between 15 and 29; -- Second 15-row page 

顺便说一句,如果可行,我会将此要求退还给设计师,以便仔细检查是否值得花费大量时间。如果您不需要显示总行数,则要简单得多。

答案 1 :(得分:1)

要在同一个COUNT(*)子句中包含SELECT,其中包含一堆详细信息行,则会失败。这是因为COUNT(*)是一个聚合函数。在没有GROUP BY的情况下,它在结果集中只返回一行。因此,您需要在自己的SELECT语句中查询计数。

SQL Server具有ROW_NUMBER()功能。 Oracle有一个名为ROWNUM的伪列。 MySQL有一个真正可怜的黑客获取行号。这里描述了它。 MySQL - Get row number on select