我正在处理观点。在一个我有购买订单的付款条款(30天,2天30天(30/60)等)和其他东西:
PO SUPPLIER DELIVERY_DATE PAYMENT_TERMS
1 A 2016-11-10 30 DAYS
2 B 2016-11-10 30/60 DAYS
我想制作一个包含付款时间表的视图。 由于许可,我不能使用表格,只有视图和我因此而遇到很多麻烦(尝试物化视图进行更新,没有运气,因为ORACLE抛出查询是复杂的)。
这就是我想要的:
PO SUPPLIER DELIVERY_DATE PAYMENT_TERMS PAYMENT_DATE AMOUNT
1 A 2016-11-10 30 DAYS 2016-12-10 100%
2 B 2016-11-10 30/60 DAYS 2016-12-10 50%
2 B 2016-11-10 30/60 DAYS 2017-01-10 50%
任何提示?
谢谢!
答案 0 :(得分:1)
好吧,您似乎需要确定Payment_Terms
的每个不同值的真正含义,因为没有内置规则将“30/60 DAYS”解释为“一次付款50% 30天后,60天后第二次支付50%“。所以,我理解为什么查询对于具有自动更新的物化视图来说太复杂了。具体来说,需要在输出中为单行输入创建多行通常需要相对复杂的逻辑(使用UNION
,花式JOIN
语句等)。
你仍然可以使用物化视图,但是你需要自己强制刷新它(定期或者必要时使用触发器)。
无论哪种方式,获得所需内容的查询(其中之一)可能如下所示:
-- build the records for 30 DAYS
select po, supplier, delivery_date, payment_terms, (delivery_date + 30) as payment_date, 100 as amount
from The_Table
where payment_terms = '30 DAYS'
union all
-- build the records for the FIRST payment for 30/60
select po, supplier, delivery_date, payment_terms, (delivery_date + 30) as payment_date, 50 as amount
from The_Table
where payment_terms = '30/60 DAYS'
union all
-- build the records for the SECOND payment for 30/60
select po, supplier, delivery_date, payment_terms, (delivery_date + 60) as payment_date, 50 as amount
from The_Table
where payment_terms = '30/60 DAYS'
希望这有帮助。
答案 1 :(得分:0)
下面的解决方案假设“30”是表示“月”的传统方式 - 所有计算都基于月而不是天。相反,“天”字面意思是,解决方案可以很容易地适应。我假设“payment_terms”sting总是以您呈现的格式(两种可能性中的一种)完全正确,并且第二个数字(如果存在)是第一个数字的精确倍数。我又添加了两个测试行。我想不出有什么理由不能将其变成快速可刷新的物化视图。 (不确定FOR UPDATE - 你想通过这个视图更新什么?)
注意 - 如果最后一列中的百分比是用于进一步的计算,则不应将它们组成字符串(以%符号结尾);相反,它们应该是数字,如1.0000或0.3333或0.5000。
with
inputs ( po, supplier, delivery_date, payment_terms ) as (
select 1, 'A', date '2016-11-10', '30 DAYS' from dual union all
select 2, 'B', date '2016-11-10', '30/60 DAYS' from dual union all
select 3, 'C', date '2015-03-13', '90 DAYS' from dual union all
select 4, 'D', date '2015-10-01', '90/270 DAYS' from dual
),
prep ( po, supplier, delivery_date, payment_terms, freq, num ) as (
select po, supplier, delivery_date, payment_terms,
to_number(regexp_substr(payment_terms, '\d+', 1, 1)) / 30,
nvl(to_number(regexp_substr(payment_terms, '\d+', 1, 2)) /
to_number(regexp_substr(payment_terms, '\d+', 1, 1)), 1)
from inputs
)
select po, supplier, delivery_date, payment_terms,
add_months ( delivery_date, freq * level ) as payment_date,
to_char(100/num, '999.99') || '%' as payment_amount
from prep
connect by level <= num
and prior po = po
and prior sys_guid() is not null
order by po, payment_date
;
PO S DELIVERY_DATE PAYMENT_TERMS PAYMENT_DATE PAYMENT_AMOUNT
---------- - ------------- ------------- ------------ --------------
1 A 10-NOV-2016 30 DAYS 10-DEC-2016 100.00%
2 B 10-NOV-2016 30/60 DAYS 10-DEC-2016 50.00%
2 B 10-NOV-2016 30/60 DAYS 10-JAN-2017 50.00%
3 C 13-MAR-2015 90 DAYS 13-JUN-2015 100.00%
4 D 01-OCT-2015 90/270 DAYS 01-JAN-2016 33.33%
4 D 01-OCT-2015 90/270 DAYS 01-APR-2016 33.33%
4 D 01-OCT-2015 90/270 DAYS 01-JUL-2016 33.33%