如何在DB2 for iSeries中使用LIMIT
?
我有一个包含超过50,000条记录的表,我想返回0到10,000条记录和10,000到20,000条记录。
我知道在SQL中,你可以在查询末尾写上 LIMIT 0,10000
来返回0到10,000条记录,以及在查询末尾写上 LIMIT 10000,10000
来返回10,000到20,000条记录。
那么,在DB2中该如何实现呢?代码和语法是什么? (最好提供完整的查询示例)
如何在DB2 for iSeries中使用LIMIT
?
我有一个包含超过50,000条记录的表,我想返回0到10,000条记录和10,000到20,000条记录。
我知道在SQL中,你可以在查询末尾写上 LIMIT 0,10000
来返回0到10,000条记录,以及在查询末尾写上 LIMIT 10000,10000
来返回10,000到20,000条记录。
那么,在DB2中该如何实现呢?代码和语法是什么? (最好提供完整的查询示例)
FETCH FIRST [n] ROWS ONLY
:
SELECT LASTNAME, FIRSTNAME, EMPNO, SALARY
FROM EMP
ORDER BY SALARY DESC
FETCH FIRST 20 ROWS ONLY;
ROW_NUMBER()
(从v5r4开始),并在WHERE
子句中使用它:(摘自此处:http://www.justskins.com/forums/db2-select-how-to-123209.html)SELECT code, name, address
FROM (
SELECT row_number() OVER ( ORDER BY code ) AS rid, code, name, address
FROM contacts
WHERE name LIKE '%Bob%'
) AS t
WHERE t.rid BETWEEN 20 AND 25;
ROW_NUMBER
不是一个有效的关键字。但感谢提供的链接,它给了我一个想法并且它可行。 - elcool我开发了以下方法:
你需要一个具有可排序的唯一值的表格。
如果你想要获取第10000行到第25000行,而你的表格共有40000行,首先需要获取起始点和总行数:
int start = 40000 - 10000;
int total = 25000 - 10000;
然后将这些代码传递给查询:
SELECT * FROM
(SELECT * FROM schema.mytable
ORDER BY userId DESC fetch first {start} rows only ) AS mini
ORDER BY mini.userId ASC fetch first {total} rows only
这是我想出的解决方案:
select FIELD from TABLE where FIELD > LASTVAL order by FIELD fetch first N rows only;
试试这个
SELECT * FROM
(
SELECT T.*, ROW_NUMBER() OVER() R FROM TABLE T
)
WHERE R BETWEEN 10000 AND 20000
@elcool的解决方案是一个聪明的想法,但你需要知道总行数(在执行查询时甚至可能会发生变化!)。因此,我提出了一个修改版,不幸的是需要使用3个子查询而不是2个:
select * from (
select * from (
select * from MYLIB.MYTABLE
order by MYID asc
fetch first {last} rows only
) I
order by MYID desc
fetch first {length} rows only
) II
order by MYID asc
其中{last}
应该替换为我需要的最后一条记录的行号,{length}
应该替换为我需要的行数,计算公式为最后一行 - 第一行 + 1
。
例如,如果我想要从第10行到第25行(共16行),{last}
将是25,{length}
将是25-10+1=16。
LIMIT
子句允许您限制查询返回的行数。 LIMIT
子句是SELECT
语句的扩展,具有以下语法:
SELECT select_list
FROM table_name
ORDER BY sort_expression
LIMIT n [OFFSET m];
在这个语法中:
n
是要返回的行数。m
是在返回 n
行之前要跳过的行数。LIMIT
子句的另一个更短的版本如下:
LIMIT m, n;
m
行并从结果集中返回接下来的 n
行。LIMIT
子句的 ORDER BY
子句,则返回的行也是未指定的。因此,最好始终将 LIMIT
子句与 ORDER BY
子句一起使用。您还应考虑使用OPTIMIZE FOR n ROWS子句。有关所有这些内容的更多详细信息,请参阅DB2 LUW文档中的限制SELECT语句的指南主题:
在DB2表上进行分页有两种有效的解决方案:
1-使用函数row_number()和子句OVER的技术,该技术已在另一篇文章中介绍过(“SELECT row_number() OVER ( ORDER BY ... )”)。在一些大型表上,我注意到有时会出现性能下降。
2-使用可滚动游标的技术。实现取决于所使用的语言。这种技术在大型表上似乎更加稳健。
我在明年的研讨会上介绍了PHP中实现的这两种技术。幻灯片可以在此链接上找到: http://gregphplab.com/serendipity/uploads/slides/DB2_PHP_Best_practices.pdf
抱歉,但此文档仅提供法语版本。
这里有可用的选项:
DB2 has several strategies to cope with this problem.
You can use the "scrollable cursor" in feature.
In this case you can open a cursor and, instead of re-issuing a query you can FETCH forward and backward.
This works great if your application can hold state since it doesn't require DB2 to rerun the query every time.
You can use the ROW_NUMBER() OLAP function to number rows and then return the subset you want.
This is ANSI SQL
You can use the ROWNUM pseudo columns which does the same as ROW_NUMBER() but is suitable if you have Oracle skills.
You can use LIMIT and OFFSET if you are more leaning to a mySQL or PostgreSQL dialect.