暂无图片
Oracle的SQL语句,红框里的两个子查询中查询逻辑是一样的,区别就是返回的字段不一样,因为需要要返回2个字段,所以需要执行两次这个子查询,有办法只执行一次子查询返回两个字段的数据吗?
我来答
分享
暂无图片 匿名用户
Oracle的SQL语句,红框里的两个子查询中查询逻辑是一样的,区别就是返回的字段不一样,因为需要要返回2个字段,所以需要执行两次这个子查询,有办法只执行一次子查询返回两个字段的数据吗?

M8AWIDQHPTZ0YG34LYIH.jpg

我来答
添加附件
收藏
分享
问题补充
4条回答
默认
最新
Thomas

两个红框输出的不可能是多条记录,只能是像标量子查询输出一条。这个写得相当绕,既然最终只输出一行,那简化成:select agentid,agentname from pmagtinf where parentid='AGE...001'; 即可。 

暂无图片 评论
暂无图片 有用 1
打赏 0
广州_老虎刘
2023-07-21
这个标量子查询的逻辑是: 根据传入的每一个不同agentid值, 逐级找到它的所有parentid, 然后再看这些parentid里面是不是有等于那个常量的记录. 如果没有会返回null, 你的简化写法没有这个逻辑, 应该是不对的. 标量子查询里面带connect by,这种写法的效率是极低的.
Thomas

刘老师,根据传入的每一个不同agentid值, 逐级找到它的所有parentid,这个是不是在 in后的括号里实现的?select agentid from 表 start witg agebtud=:a connect by prior agentid=parentid, 这里prior agentid=parentid, 翻译出来是当前记录的agentid等于后面一条记录的parentid, 换句话说,是从祖先(比如祖先agentid是AGE0000..01)开始,找出它的子子孙孙吧? 

暂无图片 评论
暂无图片 有用 0
打赏 0
Thomas

create table tb_zxp (agentid varchar2(5) primary key,agentname varchar2(20),parentid varchar2(5));
insert into tb_zxp values ('008','AABBCCDD','007');
insert into tb_zxp values ('007','AABBCC','006');
insert into tb_zxp values ('006','AABB','005');
insert into tb_zxp values ('005','AA',null);
commit;

为了方便,输出里加了agentid一列,发现两个子查询不会输出多条记录,确属标量子查询
从agentid='005'开始往下找,看输出结果:
select
(select agentid from tb_zxp p where p.parentid='005' start with p.agentid=pa.agentid connect by prior p.parentid=p.agentid) low_agentid,
(select agentname from tb_zxp p where p.parentid='005' start with p.agentid=pa.agentid connect by prior p.parentid=p.agentid) low_agentname,
agentid
from tb_zxp pa where parentid in
(select agentid from tb_zxp start with agentid='005' connect by prior agentid=parentid) ;
LOW_AGENTID LOW_AGENTNAME AGENTID
--------------- ------------------------------------------------------------ ---------------
006                  AABB                       008
006                 AABB                        007
006                AABB                        006

解释:
A. (select agentid from tb_zxp start with agentid='005' connect by prior agentid=parentid) 查出从祖先开始一级级往下的agentid
B. from tb_zxp pa where parentid in (...) 从A的结果里,剔除祖先这行,输出其余子孙行的记录,每行的agentid被后续两个子查询引用

现在从agentid='006'开始往下找,看输出结果:
select
(select agentid from tb_zxp p where p.parentid='006' start with p.agentid=pa.agentid connect by prior p.parentid=p.agentid) low_agentid,
(select agentname from tb_zxp p where p.parentid='006' start with p.agentid=pa.agentid connect by prior p.parentid=p.agentid) low_agentname,
agentid
from tb_zxp pa where parentid in
(select agentid from tb_zxp start with agentid='006' connect by prior agentid=parentid) ;
LOW_AGENTID LOW_AGENTNAME AGENTID
--------------- ------------------------------------------------------------ ---------------
007 AABBCC 008
007 AABBCC 007

暂且不分析子查询里的逻辑,看输出结果,反映了两类信息:
儿子辈的agentid和agentname
究竟有几代人(从输出的行数可知)

由此,把SQL改写如下:
with
t1 as
(select level from tb_zxp start with agentid='006' connect by prior agentid=parentid),
t2 as
(select agentid,agentname from tb_zxp where parentid='005')
select agentid,agentname from t1,t2;

AGENTID AGENTNAME
--------------- ------------------------------------------------------------
006 AABB
006 AABB
006 AABB

暂无图片 评论
暂无图片 有用 0
打赏 0
Thomas

纠正下,最后的SQL应该如下:

with
t1 as
(select lv from (select level as lv,connect_by_isleaf as isleaf from tb_zxp start with agentid='005' connect by prior agentid=parentid) where isleaf=0),
t2 as
(select agentid,agentname from tb_zxp where parentid='005')
6 select agentid,agentname from t1,t2;

AGENTID AGENTNAME
--------------- ------------------------------------------------------------
006         AABB
006         AABB
006         AABB

暂无图片 评论
暂无图片 有用 0
打赏 0
回答交流
Markdown


请输入正文
提交
相关推荐
rac节点重启导致ogg抽取进程重启,目标库数据异常
回答 3
你这个可以的,我们前期用的时候找oracle咨询,也提过这种方案。我们最终的方案其实是用的crs管理ogg,远程的总觉得有点网络消耗和不确定性,crs管理ogg也算oracle官方支持的一种解决方案吧
oracle 9i exp 导出时,带有参数flashback_scn 时,报ORA-01466 EXP-00008 EXP-00000
回答 1
看看你的完整命令。从错误号看:ORA01466DESCRIPTION:unabletoreaddatatabledefinitionhaschangedCAUSE:Queryparsedaftertb
Oracle更新到了19.12 ,sqlplus 显示 数据库还是19.3 但是查询dba_registry_history发现已经更新到了19.12
回答 1
脚本执行了吗?跑一下下面的脚本再看看。cd$ORACLEHOME/OPatch./datapatchverbose
查询最近一个月都有哪些Oracle用户登录,怎么查询?
回答 1
已采纳
可以看下dbahistactivesessionhistory,但是只能每10分钟采样一次。
19c扩展业务表空间,哪个用户查询能看到所有业务表空间使用情况
回答 4
要么在PDB里面,要么在CDB里面
请教各位,我升级报错,麻烦大家看看?
回答 2
看截图是无效对象编译执行的过程,并没有发现报错。
pdb直接互相dblink访问
回答 1
你不要把pdb理解为一个独立的database,真正的database是CDB,pdb你就理解为是它的一个组件就好了。
oracle ora-12154问题如何处理?
回答 2
已采纳
一、监听器介绍1、概念      监听器直接面向用户,也就是客户端程序。监听器启动时,负责打开监听端口,等待客户端连接。当有客户端连接时,在
DSG占用物理读很高
回答 2
已采纳
dsg不都是原厂服务的吗?直接找原厂哇
sqlsrever不用维护吗?
回答 7
用维护,而且我感觉维护起来比mysql和pg难。只不过国内用的少