Sql 如何在oracle中找到最接近的子集和
我有两张桌子: 1) 其中之一是发票,有成千上万的数据。在我的发票表中,有客户的发票及其价格。 2) 另一个是债务。在我的债务表中,有每个客户发票的总债务。Sql 如何在oracle中找到最接近的子集和,sql,oracle,Sql,Oracle,我有两张桌子: 1) 其中之一是发票,有成千上万的数据。在我的发票表中,有客户的发票及其价格。 2) 另一个是债务。在我的债务表中,有每个客户发票的总债务。 我的目标是找到最接近的金额和债务的发票。例如,我有以下表格: 债务表: CUSTOMER_ID TOTAL_DEBTS 3326660 444$ 2789514 165$ 4931541
我的目标是找到最接近的金额和债务的发票。例如,我有以下表格: 债务表:
CUSTOMER_ID TOTAL_DEBTS
3326660 444$
2789514 165$
4931541 121$
CUSTOMER_ID INVOICE_ID AMOUNT_OF_INVOICE
3326660 1a 157$
3326660 1b 112$
3326660 1c 10$
3326660 1d 94$
3326660 1e 47$
3326660 1f 35$
3326660 1g 14$
3326660 1h 132$
3326660 1i 8$
3326660 1j 60$
3326660 1k 42$
2789514 2a 86$
2789514 2b 81$
2789514 2c 99$
2789514 2d 61$
2789514 2e 16$
2789514 2f 83$
4931541 3a 11$
4931541 3b 14$
4931541 3c 17$
4931541 3d 121$
4931541 3e 35$
4931541 3f 29$
CUSTOMER_ID TOTAL_DEBTS CALCULATED_AMOUNT INVOICES_ID
3326660 444$ 444$ 1a,1b,1f,1h,1i
2789514 165$ 164$ 2b,2f
4931541 121$ 121$ 3d
发票表:
CUSTOMER_ID TOTAL_DEBTS
3326660 444$
2789514 165$
4931541 121$
CUSTOMER_ID INVOICE_ID AMOUNT_OF_INVOICE
3326660 1a 157$
3326660 1b 112$
3326660 1c 10$
3326660 1d 94$
3326660 1e 47$
3326660 1f 35$
3326660 1g 14$
3326660 1h 132$
3326660 1i 8$
3326660 1j 60$
3326660 1k 42$
2789514 2a 86$
2789514 2b 81$
2789514 2c 99$
2789514 2d 61$
2789514 2e 16$
2789514 2f 83$
4931541 3a 11$
4931541 3b 14$
4931541 3c 17$
4931541 3d 121$
4931541 3e 35$
4931541 3f 29$
CUSTOMER_ID TOTAL_DEBTS CALCULATED_AMOUNT INVOICES_ID
3326660 444$ 444$ 1a,1b,1f,1h,1i
2789514 165$ 164$ 2b,2f
4931541 121$ 121$ 3d
我的目标表是:
CUSTOMER_ID TOTAL_DEBTS
3326660 444$
2789514 165$
4931541 121$
CUSTOMER_ID INVOICE_ID AMOUNT_OF_INVOICE
3326660 1a 157$
3326660 1b 112$
3326660 1c 10$
3326660 1d 94$
3326660 1e 47$
3326660 1f 35$
3326660 1g 14$
3326660 1h 132$
3326660 1i 8$
3326660 1j 60$
3326660 1k 42$
2789514 2a 86$
2789514 2b 81$
2789514 2c 99$
2789514 2d 61$
2789514 2e 16$
2789514 2f 83$
4931541 3a 11$
4931541 3b 14$
4931541 3c 17$
4931541 3d 121$
4931541 3e 35$
4931541 3f 29$
CUSTOMER_ID TOTAL_DEBTS CALCULATED_AMOUNT INVOICES_ID
3326660 444$ 444$ 1a,1b,1f,1h,1i
2789514 165$ 164$ 2b,2f
4931541 121$ 121$ 3d
因为我的表中有成千上万的数据,所以性能对我来说非常重要。我从stackoverflow中找到代码:
但是,性能很低。当我发现Calculated_amount和total_debts之间的值相同时,我必须停止加法循环
谢谢你的帮助 使用递归查询:
with
t1 as (
select customer_id cid, total_debts dbt, invoice_id iid, amount_of_invoice amt,
row_number() over (partition by customer_id order by invoice_id) rn
from debts d join invoices i using (customer_id) ),
t2 (cid, iid, ams, dbt, amt, sma, rn) as (
select cid, cast(iid as varchar2(4000)), cast(amt as varchar2(4000)),
dbt, amt, amt, rn
from t1
union all
select t2.cid,
t2.iid || ', ' || t1.iid,
t2.ams || ', ' || t1.amt,
t2.dbt, t2.amt, t1.amt + t2.sma, t1.rn
from t2
join t1 on t1.cid = t2.cid and t1.rn > t2.rn and t2.sma + t1.amt <= t1.dbt),
t3 as (
select t2.*, rank() over (partition by cid order by dbt - sma ) rnk
from t2)
select cid, iid, ams, dbt, sma from t3 where rnk = 1
子查询T1
连接两个表并添加列rn
,该列用于合并数据<代码>T2是分层的,它完成了工作的主要部分-合并所有数据,直到总和达到债务T3
使用函数rank
筛选最佳解决方案。如您所见,对于CID
3326660,有四种最佳组合
请注意,对于大量数据,递归子查询速度很慢,并且此解决方案无法工作 对于SQL来说,这不是一个合适的问题。你需要概括所有可能的组合,看看哪一个最接近。同意@GordonLinoff,读一下这篇文章,它有助于你理解你的问题是关于什么的