DB2的LIMIT等价物
在DB2 for iSeries中,你如何做LIMIT
?
我有一个超过5万条logging的表,我想返回logging0到10,000,logging10,000到20,000。
我知道在SQL中,您在查询的末尾写入0到10000的LIMIT 10000,10000
,在10000到20,000的查询结束时写入LIMIT 0,10000
那么,这是如何在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;
开发这个方法:
您需要一个具有可以订购的唯一值的表格。
如果你想要10,000到25,000行,你的表有40,000行,首先你需要得到起点和总行数:
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
这是我提出的解决scheme:
select FIELD from TABLE where FIELD > LASTVAL order by FIELD fetch first N rows only;
通过将LASTVAL初始化为0(或者为文本字段),然后将其设置为最近一组logging中的最后一个值,这将以N个logging的块为单位遍历表。
DB2 for i 7.1和7.2最近增加了对OFFSET和LIMIT的支持。 您需要以下数据库PTF组级别才能获得此支持:
- IBM i 7.2的SF99702级别9
- 适用于IBM i 7.1的SF99701等级38
请参阅此处了解更多信息:OFFSET和LIMIT 文档 ,DB2 for i Enhancement Wiki
@ elcool的解决scheme是一个聪明的想法,但是您需要知道总的行数(在执行查询时甚至可以改变!)。 所以我提出了一个修改的版本,不幸的是需要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}
应该被我需要的最后一个logging的行号replace, {length}
应该被replace为我需要的行数,计算为last row - first row + 1
。
例如,如果我想从10行到25行(共16行), {last}
将是25, {length}
将是25-10 + 1 = 16。
您还应该考虑优化FOR n ROWS子句。 有关限制SELECT语句指南中的DB2 LUW文档中的所有内容的更多详细信息,请参见:
- OPTIMIZE FOR子句声明只检索结果的一个子集,或者优先检索只有前几行。 然后优化器可以select访问计划,以最小化检索前几行的响应时间。
有两种解决scheme可以在DB2表上高效分页:
1 – 使用函数row_number()和在另一个post(“SELECT row_number()OVER(ORDER BY …)”)上呈现的子句OVER的技术。 在一些大桌子上,我注意到有时演出会退化。
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.
尝试这个
SELECT * FROM ( SELECT T.*, ROW_NUMBER() OVER() R FROM TABLE T ) WHERE R BETWEEN 10000 AND 20000