Mat*_*tin 966 sql oracle pagination limit
有没有办法让Oracle查询表现得像包含一个MySQL limit子句?
在MySQL,我可以这样做:
select *
from sometable
order by name
limit 20,10
Run Code Online (Sandbox Code Playgroud)
获得第21行到第30行(跳过前20行,给出下一行10).在行之后选择行order by,因此它实际上按字母顺序从第20个名称开始.
在Oracle,人们提到的唯一的事情是rownum伪列,但它之前 进行了评估order by,这意味着:
select *
from sometable
where rownum <= 10
order by name
Run Code Online (Sandbox Code Playgroud)
将返回按名称排序的十行的随机集合,这通常不是我想要的.它也不允许指定偏移量.
Kos*_*801 770
您可以使用子查询
select *
from
( select *
from emp
order by sal desc )
where ROWNUM <= 5;
Run Code Online (Sandbox Code Playgroud)
还可以查看主题On ROWNUM并在Oracle/AskTom上限制结果以获取更多信息.
更新:为了限制下限和上限的结果,事情会变得更加臃肿
select * from
( select a.*, ROWNUM rnum from
( <your_query_goes_here, with order by> ) a
where ROWNUM <= :MAX_ROW_TO_FETCH )
where rnum >= :MIN_ROW_TO_FETCH;
Run Code Online (Sandbox Code Playgroud)
(从指定的AskTom文章复制)
更新2:从Oracle 12c(12.1)开始,有一种语法可用于限制行或从偏移量开始.
SELECT *
FROM sometable
ORDER BY name
OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY;
Run Code Online (Sandbox Code Playgroud)
有关更多示例,请参阅此答案.感谢Krumia的暗示.
sam*_*ris 535
从Oracle 12C R1(12.1)开始,那里是一个行限制性条款.它不使用熟悉的LIMIT语法,但它可以通过更多选项更好地完成工作.您可以在此处找到完整语法.
要回答原始问题,这是查询:
SELECT *
FROM sometable
ORDER BY name
OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY;
Run Code Online (Sandbox Code Playgroud)
(对于早期的Oracle版本,请参阅此问题中的其他答案)
以下示例引用链接页面,以防止链接腐烂.
CREATE TABLE rownum_order_test (
val NUMBER
);
INSERT ALL
INTO rownum_order_test
SELECT level
FROM dual
CONNECT BY level <= 10;
COMMIT;
Run Code Online (Sandbox Code Playgroud)
SELECT val
FROM rownum_order_test
ORDER BY val;
VAL
----------
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
9
9
10
10
20 rows selected.
Run Code Online (Sandbox Code Playgroud)
N行SELECT val
FROM rownum_order_test
ORDER BY val DESC
FETCH FIRST 5 ROWS ONLY;
VAL
----------
10
10
9
9
8
5 rows selected.
Run Code Online (Sandbox Code Playgroud)
N行中,如果N日行有关系,让所有的束缚行SELECT val
FROM rownum_order_test
ORDER BY val DESC
FETCH FIRST 5 ROWS WITH TIES;
VAL
----------
10
10
9
9
8
8
6 rows selected.
Run Code Online (Sandbox Code Playgroud)
x的行数SELECT val
FROM rownum_order_test
ORDER BY val
FETCH FIRST 20 PERCENT ROWS ONLY;
VAL
----------
1
1
2
2
4 rows selected.
Run Code Online (Sandbox Code Playgroud)
SELECT val
FROM rownum_order_test
ORDER BY val
OFFSET 4 ROWS FETCH NEXT 4 ROWS ONLY;
VAL
----------
3
3
4
4
4 rows selected.
Run Code Online (Sandbox Code Playgroud)
SELECT val
FROM rownum_order_test
ORDER BY val
OFFSET 4 ROWS FETCH NEXT 20 PERCENT ROWS ONLY;
VAL
----------
3
3
4
4
4 rows selected.
Run Code Online (Sandbox Code Playgroud)
zel*_*ldi 179
我对以下方法进行了一些性能测试:
select * from (
select a.*, ROWNUM rnum from (
<select statement with order by clause>
) a where rownum <= MAX_ROW
) where rnum >= MIN_ROW
Run Code Online (Sandbox Code Playgroud)
select * from (
<select statement with order by clause>
) where myrow between MIN_ROW and MAX_ROW
Run Code Online (Sandbox Code Playgroud)
select * from (
select statement, rownum as RN with order by clause
) where a.rn >= MIN_ROW and a.rn <= MAX_ROW
Run Code Online (Sandbox Code Playgroud)
表有1000万条记录,排序在未编入索引的日期时间行:
选择前10行:
选择100,000到100,010之间的行:
选择9,000,000到9,000,010之间的行:
Lei*_*fel 53
只有一个嵌套查询的分析解决方案:
SELECT * FROM
(
SELECT t.*, Row_Number() OVER (ORDER BY name) MyRow FROM sometable t
)
WHERE MyRow BETWEEN 10 AND 20;
Run Code Online (Sandbox Code Playgroud)
Rank()Row_Number()如果名称有重复值,则可以替换但可能会返回比预期更多的记录.
bel*_*daz 29
在Oracle 12c上(参见SQL参考中的行限制子句):
SELECT *
FROM sometable
ORDER BY name
OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY;
Run Code Online (Sandbox Code Playgroud)
Vla*_*cea 25
由于版本 12c Oracle 支持 SQL:2008 标准,它提供以下语法来限制 SQL 结果集:
SELECT
title
FROM
post
ORDER BY
id DESC
FETCH FIRST 50 ROWS ONLY
Run Code Online (Sandbox Code Playgroud)
在版本 12c 之前,要获取Top-N记录,您必须使用派生表和ROWNUM伪列:
SELECT *
FROM (
SELECT
title
FROM
post
ORDER BY
id DESC
)
WHERE ROWNUM <= 50
Run Code Online (Sandbox Code Playgroud)
小智 14
在Oracle中,带有排序的分页查询非常棘手.
Oracle提供了一个ROWNUM伪列,它返回一个数字,指示数据库从一个表或一组连接视图中选择行的顺序.
ROWNUM是一个伪列,让许多人陷入困境.ROWNUM值不会永久分配给一行(这是一种常见的误解).实际分配ROWNUM值时可能会造成混淆.在通过查询的筛选谓词但在查询聚合或排序之前,将 ROWNUM值分配给行.
更重要的是,ROWNUM值仅在分配后才会递增.
这就是followin查询不返回任何行的原因:
select *
from (select *
from some_table
order by some_column)
where ROWNUM <= 4 and ROWNUM > 1;
Run Code Online (Sandbox Code Playgroud)
查询结果的第一行不传递ROWNUM> 1谓词,因此ROWNUM不会增加到2.因此,没有ROWNUM值大于1,因此查询不返回任何行.
正确定义的查询应如下所示:
select *
from (select *, ROWNUM rnum
from (select *
from skijump_results
order by points)
where ROWNUM <= 4)
where rnum > 1;
Run Code Online (Sandbox Code Playgroud)
在我关于Vertabelo博客的文章中了解有关分页查询的更多信息:
Luk*_*zda 11
作为公认答案的扩展,Oracle 在内部使用ROW_NUMBER/RANK函数。OFFSET FETCH语法是一种语法糖。
可以通过使用DBMS_UTILITY.EXPAND_SQL_TEXT程序来观察:
准备样品:
CREATE TABLE rownum_order_test (
val NUMBER
);
INSERT ALL
INTO rownum_order_test
SELECT level
FROM dual
CONNECT BY level <= 10;
COMMIT;
Run Code Online (Sandbox Code Playgroud)
询问:
SELECT val
FROM rownum_order_test
ORDER BY val DESC
FETCH FIRST 5 ROWS ONLY;
Run Code Online (Sandbox Code Playgroud)
是常规的:
SELECT "A1"."VAL" "VAL"
FROM (SELECT "A2"."VAL" "VAL","A2"."VAL" "rowlimit_$_0",
ROW_NUMBER() OVER ( ORDER BY "A2"."VAL" DESC ) "rowlimit_$$_rownumber"
FROM "ROWNUM_ORDER_TEST" "A2") "A1"
WHERE "A1"."rowlimit_$$_rownumber"<=5 ORDER BY "A1"."rowlimit_$_0" DESC;
Run Code Online (Sandbox Code Playgroud)
获取扩展的 SQL 文本:
declare
x VARCHAR2(1000);
begin
dbms_utility.expand_sql_text(
input_sql_text => '
SELECT val
FROM rownum_order_test
ORDER BY val DESC
FETCH FIRST 5 ROWS ONLY',
output_sql_text => x);
dbms_output.put_line(x);
end;
/
Run Code Online (Sandbox Code Playgroud)
WITH TIES扩展为RANK:
declare
x VARCHAR2(1000);
begin
dbms_utility.expand_sql_text(
input_sql_text => '
SELECT val
FROM rownum_order_test
ORDER BY val DESC
FETCH FIRST 5 ROWS WITH TIES',
output_sql_text => x);
dbms_output.put_line(x);
end;
/
SELECT "A1"."VAL" "VAL"
FROM (SELECT "A2"."VAL" "VAL","A2"."VAL" "rowlimit_$_0",
RANK() OVER ( ORDER BY "A2"."VAL" DESC ) "rowlimit_$$_rank"
FROM "ROWNUM_ORDER_TEST" "A2") "A1"
WHERE "A1"."rowlimit_$$_rank"<=5 ORDER BY "A1"."rowlimit_$_0" DESC
Run Code Online (Sandbox Code Playgroud)
和偏移:
declare
x VARCHAR2(1000);
begin
dbms_utility.expand_sql_text(
input_sql_text => '
SELECT val
FROM rownum_order_test
ORDER BY val
OFFSET 4 ROWS FETCH NEXT 4 ROWS ONLY',
output_sql_text => x);
dbms_output.put_line(x);
end;
/
SELECT "A1"."VAL" "VAL"
FROM (SELECT "A2"."VAL" "VAL","A2"."VAL" "rowlimit_$_0",
ROW_NUMBER() OVER ( ORDER BY "A2"."VAL") "rowlimit_$$_rownumber"
FROM "ROWNUM_ORDER_TEST" "A2") "A1"
WHERE "A1"."rowlimit_$$_rownumber"<=CASE WHEN (4>=0) THEN FLOOR(TO_NUMBER(4))
ELSE 0 END +4 AND "A1"."rowlimit_$$_rownumber">4
ORDER BY "A1"."rowlimit_$_0"
Run Code Online (Sandbox Code Playgroud)
对于 21c 版本,您可以简单地应用限制,如下所示:
select * from course where ROWNUM <=10;
Run Code Online (Sandbox Code Playgroud)
少SELECT语句.此外,性能消耗较少.致记:anibal@upf.br
SELECT *
FROM (SELECT t.*,
rownum AS rn
FROM shhospede t) a
WHERE a.rn >= in_first
AND a.rn <= in_first;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1338902 次 |
| 最近记录: |