oracle查询结果中嵌套两层子查询,报错无效标识符
到了新的项目组需要接触oracle,但是以前用的大多数都是mysql,sqlserver。像oracle这种土豪配置还是第一次在项目中使用。废话不多说了,进入今天的主题。
项目中有这样的需求,比如我查询A表中的一条记录,然后查询最近一次更新这条记录的人,更新的日志在另外一张表B。那么用Oracle怎么实现呢
首先不能链表,如果链表a表的一天记录会出现多次,因为A->B是1:n的关系。
用mysql的方式大概就是在结果中嵌套一层子查询
select (select user_name from B where A.user_id =B.user_id order by update_time desc limit 1)
from A
但是除了mysql和pg库,Oracle或者sqlserver可没有limit关键字。他们只有通过rownum进行限制,这样oracle势必会多一层嵌套
select (selecte user_name from (select user_name from B where A.user_id =B.user_id order by update_time desc) where rownum =1)
from A
满以为这样就可以解决,因为以前用sqlserver这样是没有问题的。但是在oracle就是有问题。
果然,报错A.user_id为无效标识符!
纳尼?!
后面在网上各种找,都找不到解决办法,但是都说了这个是部分oracle的bug,这个我不得而知,但是不能这样写的事实就是这样。但是网上都没有人解决。
但是总不能给领导说这个功能不能实现把。所以又不停的找,最后找到一个帖子说了oracle论坛的解决方案。
解决办法
oracle一个论坛中帖子
https://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:1853075500346799932#185916940034636142
前面说了那么多也就是我这个问题的描述,
重点看这段sql
> SELECT m.material_id, m.content_id,
(SELECT max(file_location) keep (dense_rank first order by resolution desc)
FROM mat
使用keep函数
使用keep函数进行排序,取最大的那一个,当然你也可以倒序取。
如此这个问题解决了!
当然如果没有排序和一对多的问题那么可以通过总体进行一次嵌套,或者join表。这个可以根据性能或者业务来选择。