SQL语言艺术示例一(rownum)

[size=medium]这几天我在看《SQL语言艺术》的电子版。
有这样一个简单的例子:不是经理的员工当中,哪五个人收入最高。“找出不是经理的员工”是其中的关系操作部分,由此获得一个有限的员工集合,然后排序。有些SQL方言通过在select语句中增加特殊子句来限制返回的记录数,很显然,排序和限制记录数都是非关系操作。其他SQL方言(这里主要是指Oracle)则采用另外的机制,即用一个名为rownum的虚拟字段(dummy column)为查询结果编号——这意味着编号工作发生在关系操作阶段。如果查询语句如下:[/size]

select empname,salary from employees
where status != 'EXECUTIVE'
and rownum <= 5
order by salary desc


[size=medium]乍一看好像没问题,但输出结果却不符合要求,并没有返回不是经理的人中“收入最高的五位”,而是返回不是经理的人中“最先被查到的五位”,以收入递减序返回。他们可能恰好是“收入最低的五位”!(这是Oracle实践者都知道的陷阱,大家都中过招。)
现在分析一下上面的代码。查询的关系操作部分仅从employees表中,以完全不可知的顺序,
取出最先发现的五位非经理人员(只包含empname和salary字段)。别忘了关系理论指出,关系
(以及描述关系的表)是无序的,关系中的元组(即记录)可以被存储或检索。上面的查询执
行后,收入最高的非经理人员或许在查询结果中,或许不在,无从知道查询结果是否满足查询
条件。正确的操作是:找出所有的非经理人员,以收入递减排序,然后返回前五条记录。代码如下:[/size]

select * from (
select empname,salary from employees
where status != 'EXECUTIVE'
order by salary desc )
where rownum <= 5

[size=medium]看来,有些看似关系的概念其实并不属于关系操作的范畴,因为关系操作必须要有关系操作符
的参与。上面的子查询用了order by为结果集排序,而一旦用了排序操作,该数据集就已经不
是关系了(关系是无序的)。于是外层的select看似关系操作,但其实是对一个内嵌视图的结果集进行操作,其中的order by子句早已不是关系操作了。[/size]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值