我正在构建一个网格机制,我需要从数据库中检索找到的总数或记录数,只检索一系列带有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会有多贵?
答案 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