相当于LIMIT for DB2

时间:2010-10-07 19:28:04

标签: db2 limit ibm-midrange

如何在DB2 for iSeries中执行LIMIT

我有一张包含超过50,000条记录的表格,我希望将记录返回0到10,000,并记录10,000到20,000个。

我在SQL中知道你在查询结尾处编写LIMIT 0,10000 0到10,000,在查询结尾处编写LIMIT 10000,10000 10000到20,000

那么,这在DB2中是如何完成的?什么是代码和语法? (完整查询示例表示赞赏)

10 个答案:

答案 0 :(得分:133)

使用FETCH FIRST [n] ROWS ONLY

http://publib.boulder.ibm.com/infocenter/dzichelp/v2r2/index.jsp?topic=/com.ibm.db29.doc.perf/db2z_fetchfirstnrows.htm

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;

答案 1 :(得分:12)

开发此方法:

您需要一张具有可以订购的唯一值的表格。

如果您想要行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

答案 2 :(得分:8)

最近在DB2 for i 7.1和7.2中添加了对OFFSET和LIMIT的支持。您需要以下DB PTF组级别才能获得此支持:

  • IBM i 7.2的SF99702第9级
  • IBM i 7.1的SF99701 38级

有关更多信息,请参见此处:OFFSET和LIMIT documentation,DB2 for i Enhancement Wiki

答案 3 :(得分:5)

以下是我提出的解决方案:

select FIELD from TABLE where FIELD > LASTVAL order by FIELD fetch first N rows only;

通过将LASTVAL初始化为0(或“对于文本字段”),然后将其设置为最新记录集中的最后一个值,这将以N个记录的块为单位逐步执行该表。

答案 4 :(得分:2)

@elcool's solution是一个明智的想法,但你需要知道总行数(在执行查询时甚至可以改变行!)。所以我提出了一个修改版本,遗憾的是需要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}应替换为我需要的行数,计算为last row - first row + 1

E.g。如果我想要10到25行(总共16行),{last}将为25而{length}将为25-10 + 1 = 16。

答案 5 :(得分:1)

您还应该考虑OPTIMIZE FOR n ROWS子句。有关所有这些内容的更多详细信息,请参阅Guidelines for restricting SELECT statements主题中的DB2 LUW文档:

  • OPTIMIZE FOR子句声明意图仅检索结果的子集或优先检索前几行。然后,优化器可以选择最小化检索前几行的响应时间的访问计划。

答案 6 :(得分:1)

试试这个

SELECT * FROM
    (
        SELECT T.*, ROW_NUMBER() OVER() R FROM TABLE T
    )
    WHERE R BETWEEN 10000 AND 20000

答案 7 :(得分:0)

有两种解决方案可以有效地在DB2表上进行分页:

1 - 使用函数row_number()和已在另一篇文章(“SELECT row_number()OVER(ORDER BY ...)”)上显示的子句OVER的技术。在一些大桌子上,我注意到有时性能会下降。

2 - 使用可滚动游标的技术。实现取决于使用的语言。这种技术在大桌子上似乎更加强大。

我在明年的研讨会上介绍了用PHP实现的2种技术。幻灯片可在此链接上找到: http://gregphplab.com/serendipity/uploads/slides/DB2_PHP_Best_practices.pdf

很抱歉,此文档仅提供法语版本。

答案 8 :(得分:0)

Theres这些可用选项: -

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.  

答案 9 :(得分:0)

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 行。

表可以以未指定的顺序存储行。如果您不将 ORDER BY 子句与 LIMIT 子句一起使用,则返回的行也是未指定的。因此,最好始终将 ORDER BY 子句与 LIMIT 子句一起使用。

有关详细信息,请参阅 Db2 LIMIT