暂无图片
开窗函数虚拟伪劣无法固定
我来答
分享
许肖肖
2023-06-01
开窗函数虚拟伪劣无法固定

各位老师好,遇到了一个开窗函数 显示的伪劣,在最里层的时候显示的1  在最外层的时候RN变成了13


完整sql如下:


select * from (
select tmpub_FinInstitutionType.name Typename,
cdmc_financepay.contractid contractid,
tmpub_fininstitutions.name finname,
cdmc_financepay.pk_financepay as pk_financepay,
substr(cdmc_finexecute.busidate, 0, 10) busidate,
org_orgs.code orgscode,
org_orgs.name orgsname,
org_orgs.mnecode orgsmnecode,
(cdmc_finexecute.leftrepayamount * (fi_ratecode.yrate / 100)) LX,
to_number(to_date(substr(cdmc_financepay.contenddate, 0, 10),
'yyyy-mm-dd') -
to_date(substr(cdmc_financepay.loandate, 0, 10),
'yyyy-mm-dd')) ts,
substr(cdmc_financepay.loandate, 0, 10) || '/' ||
substr(cdmc_financepay.contenddate, 0, 10) dkqx, /*借款结束日期*/
cdmc_contract.contractname,
fi_ratecode.ratename,
ceil(monthS_BETWEEN(TO_date(substr(cdmc_financepay.contenddate,
0,
10),
'YYYY/MM/DD'),
TO_date(substr(cdmc_financepay.loandate, 0, 10),
'YYYY/MM/DD')) / 12) AS DIFF_YEARS,
(case
when ceil(monthS_BETWEEN(TO_date(substr(cdmc_financepay.contenddate,
0,
10),
'YYYY/MM/DD'),
TO_date(substr(cdmc_financepay.loandate,
0,
10),
'YYYY/MM/DD')) / 12) > 5 then
(select fi_rate.yrate
from fi_ratecode fi_rate
where fi_rate.rateid = ('5年以上LPR'))
else
(select fi_rate.yrate
from fi_ratecode fi_rate
where fi_rate.rateid = ('5年以下LPR'))
end) LPR,

(fi_ratecode.yrate - (case
when ceil(monthS_BETWEEN(TO_date(substr(cdmc_financepay.contenddate,
0,
10),
'YYYY/MM/DD'),
TO_date(substr(cdmc_financepay.loandate,
0,
10),
'YYYY/MM/DD')) / 12) > 5 then
(select fi_rate.yrate
from fi_ratecode fi_rate
where fi_rate.rateid = ('5年以上LPR'))
else
(select fi_rate.yrate
from fi_ratecode fi_rate
where fi_rate.rateid = ('5年以下LPR'))
end) * 100) cy,
(case
when cdmc_finexecute.repayamount is null then
cdmc_financepay.loanmny /*放款金额*/
else
cdmc_finexecute.leftrepayamount
end) leftrepayamount,
row_number() over(partition by cdmc_finexecute.pk_financepay, substr(cdmc_finexecute.busidate, 0, 4) order by cdmc_finexecute.busidate desc) as rn
from cdmc_financepay cdmc_financepay /*贷款放款*/
left join cdmc_finexecute cdmc_finexecute /*执行情况*/
on cdmc_finexecute.pk_financepay = cdmc_financepay.pk_financepay
left join tmpub_fininstitutions
on tmpub_fininstitutions.pk_fininstitution =
cdmc_financepay.fininstitutionid
left outer join org_orgs
on org_orgs.pk_org = cdmc_financepay.pk_org
left join cdmc_contract
on cdmc_financepay.contractid = cdmc_contract.pk_contract
left outer join fi_ratecode
on cdmc_financepay.pk_rate = fi_ratecode.pk_ratecode
left join tmpub_FinVar
on tmpub_FinVar.pk_finvariety = cdmc_contract.transacttype
left join tmpub_FinInstitutionType
on tmpub_FinInstitutionType.pk_fininstitutiontype =
tmpub_fininstitutions.pk_fininstitutiontype
where cdmc_financepay.dr = '0'
and nvl(cdmc_finexecute.dr, 0) <> '1'
and cdmc_financepay.busistatus /*单据状态*/
in (1, 2)
--and cdmc_contract.contractname='20230516集团本部在中国银行借款一年期1亿元'
) temp
where temp.contractname='20230516集团本部在中国银行借款一年期1亿元'
--and temp.rn=1

;

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

因为关联 cdmc_contract 这个表的时候是左关联的右侧,因此关联查询后,这个字段可能有空值,当条件等于一个非空值时,会把空的记录都过滤掉,同一个partition内的行数发生了变化,序号就不一样了

暂无图片 评论
暂无图片 有用 1
打赏 0
暂无图片
刘贵宾

你在最外层查询语句中,只选择了符合条件 temp.contractname='20230516集团本部在中国银行借款一年期1亿元' 的记录,并没有限制 rn=1。因此,这个查询结果将包含具有相同 contractname 的多个记录,这些记录可能在不同的分区中具有不同的排名 rn。所以结果显示的 RN 变成了 13,而不是 1。

暂无图片 评论
暂无图片 有用 0
打赏 2
chengang

当在rn =1 时,子查询进行contractname 过滤。只有一行。 那么rn肯定就为1

当rn = 13 时, 子查询并没有进行contractname 过滤,所以是按子查询结果来排行的。 得取一个新的结果集后,在外层查询才又对 contractname 过滤

你两个写法,语义都是完全不同的。结果肯定不能相等

暂无图片 评论
暂无图片 有用 0
打赏 0
许肖肖

感谢各位大佬们的耐心指导与分析,该问题确实如老师说的一样(((因为关联 cdmc_contract 这个表的时候是左关联的右侧,因此关联查询后,这个字段可能有空值,当条件等于一个非空值时,会把空的记录都过滤掉,同一个partition内的行数发生了变化,序号就不一样了))),因为有空值,  所以返回了一个13  ,  

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


请输入正文
提交
相关推荐
一个ORACLE数据文件损坏 现在可以offline故障的数据文件启动ORACLE. 目前只有一周前的rman备份 归档只有最近两天
回答 2
已采纳
这个简单,先restore一周前的备份,然后改一下数据文件头的scn,如果需要一周前的数据即可的话,直接把scn改到当前值然后recover,如果需要数据尽量准确,scn改到2天前,然后应用最近两天的
RAC 19C在打32895426补丁过程中,报如下错误,请问如何解决。
回答 6
记起来了,你这错误就是因为有其他的Oracle用户登录系统了,退到root或者直接退出即可,然后解决问题后继续执行打补丁/app/app/19.0.0.0/grid/OPatch/opatchauto
应用连接oracle数据库异常端口
回答 6
如果有防火墙,也需要检查一下防火墙长连接相关的配置
oracle慢sql的where条件都是冒号加数字,怎么办
回答 4
不过一般情况下不用,看SQL执行计划的方法很多,直接看执行计划就好了,不需要实际跑一下SQL才可以看的
oracle的补丁都是修复安全问题的吗 ?
回答 1
已采纳
也有是处理bug的。bug不是安全,是缺陷。比如执行一个命令应该成功的,但是报错退出了。这种不影响性能,但是影响使用。当然有的是管安全的。
查询日志,发现3天前有一段存储过程异常00060死锁,如何和确认造成死锁的sql
回答 1
ora00060会自动生成对应的trace文件,从trace可以看到相关的SQL。
ACID 是什么?它在数据库中的作用是什么?
回答 2
已采纳
ACID是数据库管理系统(DBMS)中用于确保数据事务正确执行的四个基本特性的缩写。每个字母代表一个特性:原子性(Atomicity):原子性要求一个事务中的所有操作要么全部成功,要么全部失败。如果事
Oracle表空间加密,忘记wallet密码如何解密?
回答 2
基本无解。可以尝试暴力破解,如果隐约觉得自己的密码不是特别复杂。
请教一个Win+Oracle 11.2.0.1连接的问题
回答 1
监听日志可以备份后清理一下,alter是否还有其他错误,比如:process连接数达到最大限制。如果有,修改最大连接数重启数据库。
10053,10046 看这个样子有1000多个事件可以跟踪是不是?
回答 1
已采纳
1005310046都是主要针对特定的sql进行分析的,10046是执行过程分析,10053是执行计划产生的分析