暂无图片
开窗函数虚拟伪劣无法固定
我来答
分享
许肖肖
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
暂无图片
刘贵宾

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

暂无图片 评论
暂无图片 有用 0
chengang

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

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

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

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

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

暂无图片 评论
暂无图片 有用 0
回答交流
提交
问题信息
请登录之后查看
邀请回答
暂无人订阅该标签,敬请期待~~
暂无图片墨值悬赏