DB2 中的 ROW_NUMBER()

Posted

技术标签:

【中文标题】DB2 中的 ROW_NUMBER()【英文标题】:ROW_NUMBER() in DB2 【发布时间】:2014-11-28 07:35:41 【问题描述】:

如何在 DB2 数据库的 where 子句中使用 ROW_NUMBER()。 我在下面尝试过,但没有成功:

SELECT * FROM CSPAPP.LOCATIONS
WHERE (ROW_NUMBER() OVER(ORDER BY LOCATION)) BETWEEN 100 AND 200

报错:聚合函数或OLAP函数的使用无效。

我也尝试了以下方法:

SELECT (ROW_NUMBER() OVER(ORDER BY LOCATION)) AS RN ,* FROM CSPAPP.LOCATIONS
WHERE RN < 200

SELECT (ROW_NUMBER() OVER(ORDER BY LOCATION)) AS RN ,LOCATION FROM CSPAPP.LOCATIONS
WHERE RN < 200

【问题讨论】:

【参考方案1】:

您不能在定义别名的同一级别上引用别名。您需要将其包装到派生表中:

SELECT location
FROM (
   SELECT row_number() over(order by location) as rn, 
          location 
   FROM cspapp.locations
)   
WHERE rn < 200

【讨论】:

非常感谢您的解决方案,但它部分符合我的目的。我正在尝试 SELECT * FROM ( SELECT row_number() over(order by location) as rn ,* FROM cspapp.locations ) WHERE rn 哎呀。对不起。错误是:“在 'by location) 之后发现了意外的令牌 *,因为 rn。预期的令牌可能包括:。”我无法输入每一列,因为表中大约有 600 列。所以我必须使用 * 一次选择所有列。 可能location是DB2中的保留字,我不知道 我认为 select column_name,* from Table_name 在 DB2 中是不允许的,这在 SQL Server 中是允许的。有什么想法??? 然后为*添加前缀:select row_number() ... , table_name.* from table_name(或使用别名)【参考方案2】:

在 iSeries DB2 中根据行号进行选择时,我使用了类似的方法:

SELECT *
FROM (
    SELECT ROW_NUMBER() OVER(ORDER BY location) as RRN, *
    FROM CSPAPP.LOCATIONS
    )
WHERE RRN between 100 and 200

如果您只对 1 个字段感兴趣,您可以为选择和引用字段指定名称:

SELECT DATA.location
FROM (
    SELECT ROW_NUMBER() OVER(ORDER BY location) as RRN, *
    FROM CSPAPP.LOCATIONS
    ) as DATA
WHERE DATA.RRN between 100 and 200

【讨论】:

感谢您的帮助。我尝试了类似这样的操作:SELECT * FROM cspapp.locations WHERE LOCATION IN (SELECT location FROM (SELECT row_number() over(order by location) as rno,LOCATION FROM cspapp.位置)WHERE rno BETWEEN 1000 AND 10000)。它起作用了。【参考方案3】:

您可以尝试 FETCH FIRST 200 ROWS ONLY 而不是 row_number。像平常一样编写你的选择,没有 ROW_NUMBER,按你需要的任何顺序排序,然后 FETCH FIRST x。

选择带有“*”的所有列不是一个好习惯尤其是如果您有 600 多个列(这本身就是糟糕的数据库设计)。

【讨论】:

【参考方案4】:

不使用 row_number() 函数:

SELECT * FROM 
(SELECT * FROM CSPAPP.LOCATIONS ORDER BY LOCATION FETCH FIRST 200 rows only)
ORDER BY LOCATION DESC FETCH FIRST 100 rows only;

With Row number:

SELECT ROW_NUMBER() OVER(ORDER BY LOCATIONS), LOCATIONS as RNM FROM 
(SELECT * FROM CSPAPP.LOCATIONS ORDER BY LOCATIONS FETCH FIRST 200 rows only)
ORDER BY LOCATIONS DESC FETCH FIRST 100 rows only;

【讨论】:

【参考方案5】:

您可以在定义别名的同一级别上引用别名。您需要将其包装到派生表中:

SELECT T1.* FROM(
       SELECT row_number() over(order by location) as rn ,L.* 
       FROM cspapp.locations L) As T1 
WHERE T1.rn < 200

但您应该明白* 绝不是最佳实践。您应该使用列名而不是 * (L.col1)。

【讨论】:

以上是关于DB2 中的 ROW_NUMBER()的主要内容,如果未能解决你的问题,请参考以下文章

SQL Row_Number() 不排序日期

在 db2 中使用 row_number()

使用ROW_NUMBER()将复杂的DB2 SQL转换为mongo查询

SQL分页查询的几种方式

求解:db2数据库表Tab中无id,且数据量较大,如何指定查询中间十条数据,不是前十条,谢了。

db2 OLAP函数使用