Oracle SQL Rownum语法问题

时间:2014-05-30 23:30:28

标签: sql oracle

我正在尝试编写具有以下功能的查询:

1)从名为EMPLOYEE的表中选择与$ city变量匹配到表列CITY的所有内容以及在我的EMPLOYEE表中使用NAME列的变量$ search,而不必关心区分大小写。

2)我想将结果限制为显示第11-20行

我从以下开始:

select * from (select rownum rn, NAME, ADDRESS, POSTAL, PHONE, MAP from EMPLOYEE) where rn >= 11 and rn <= 20;

这使我可以看到第11-20行,而不会将结果缩小到特定的城市和搜索词,这是一个开始。

我尝试修改上述声明以达到我的目标:

select * from (select rownum rn, NAME, ADDRESS, POSTAL, PHONE, MAP from EMPLOYEE) where rn >= 11 and rn <= 20 and CITY= $city and LOWER(NAME) like LOWER('%$search%');

我也尝试将语句的顺序更改为:

select * from (select rownum rn, NAME, ADDRESS, POSTAL, PHONE, MAP from EMPLOYEE) where CITY= $city and LOWER(NAME) like LOWER('%$search%') and rn >= 11 and rn <= 20;

我对Oracle很新......

如果有人可以解释为什么我的思维过程不起作用,那也是值得赞赏的。

2 个答案:

答案 0 :(得分:0)

我对rownum有一种内心的反应,因为它是一只奇怪的野兽。输出数据时它会递增 - 这是查询的最后一步。具有讽刺意味的是,如果查询没有返回任何数据,那么rownum永远不会递增。这会导致rownum > 1永远不会返回结果,因为第一行永远不会在结果集中返回。

我建议你改用row_number()。这在性能方面稍贵一些,但它会做正确的事情。这是一个例子:

select e.* 
rom (select row_number() over (order by name) as rn, NAME, ADDRESS, POSTAL, PHONE, MAP
     from EMPLOYEE
    ) e 
where rn >= 11 and rn <= 20;

rownum的行为实际上已在Oracle documentation中很好地记录了。

编辑:

当然,rownum在您使用子查询时可以正常工作。您只需将where条件移动到子查询中:

select e.*
from (select rownum rn, NAME, ADDRESS, POSTAL, PHONE, MAP
      from EMPLOYEE e
      where CITY = $city and LOWER(NAME) like LOWER('%$search%')
     ) e
where rn >= 11 and rn <= 20;

答案 1 :(得分:0)

关于问题的第2部分:“我想将结果限制为显示第11-20行”。 严格来说,这个要求没有多大意义。 Oracle将表的数据解释为堆,没有任何序列,只要您未在查询中指定“order by”子句,Oracle就不保证获取数据的顺序。 因为您没有提到查询输出的排序,所以不需要“order by”子句。因此,您的Oracle查询将提供危险的数据序列。

因为您想要将输出行数限制为10,所以您的查询(无替换)可能写成如下:

 select NAME, ADDRESS, POSTAL, PHONE, MAP from EMPLOYEE where rownum < 11;

关于变量替换,它取决于查询执行的类型。例如。交互式地来自SQL * Plus,来自* .sql脚本,来自UNIX或其他操作系统上的shell脚本的sql脚本调用,来自HERE文档,嵌入在shell脚本中,来自PL / SQL。