Oracle相关子查询问题
Posted
技术标签:
【中文标题】Oracle相关子查询问题【英文标题】:Oracle correlated subquery issue 【发布时间】:2012-09-28 02:56:42 【问题描述】:我有以下架构
Invoices
=================
invoice_number
account_id
invoice_amount
invoice_date
status ("Paid","Not Paid")
我正在尝试编写查询以获取包含以下信息的所有发票...
发票号码 发票日期 帐户 ID 发票金额 此帐户 ID 的最后支付发票金额(此行的发票日期之前)我对最后一件商品(最后支付的发票金额)有疑问。到目前为止,我...
select
inv2.invoice_number,
inv2.invoice_date,
inv2.account_id,
inv2.invoice_amount,
(
select * from (
select inv.invoice_amount
from invoices inv
where inv.account_id = inv2.account_id
and inv.status = 'PAID'
and inv.invoice_date < inv2.invoice_date
order by inv.invoice_date desc
)
where rownum <=1
) as last_paid_amount
from
invoices inv2
我正在尝试重构它以不使用相关子查询,因为我的数据集的大小使得这非常昂贵。如何重构以使用不相关的子查询。这甚至可能吗?
谢谢
【问题讨论】:
【参考方案1】:我可能在这里搞砸了order by
子句,因为我现在没有机会测试它,但想法是使用 LAG 函数:
select
inv2.invoice_number,
inv2.invoice_date,
inv2.account_id,
inv2.invoice_amount,
lag(invoice_amount) over(
partiton by account_id
order by invoice_date, decode(status, 'PAID', 1, 0)
) last_paid_amount
from
invoices inv2
【讨论】:
除非我遗漏了什么,否则为了让 LAG 发挥作用,付款发票不得超过 1 张。【参考方案2】:select a.*, case when rnk = 1 then invoice_amount end as last_paid_amount
from(select
inv2.invoice_number,
inv2.invoice_date,
inv2.account_id,
inv2.invoice_amount,
row_number() over(partition by invoice_number, account_id, (case when status = 'PAID' then 0 else 1 end), invoice_date desc) as rnk
from
invoices inv2) a
顺便说一句,我不确定 LAG 是否可以在这里工作。
【讨论】:
以上是关于Oracle相关子查询问题的主要内容,如果未能解决你的问题,请参考以下文章