[英]Can I use Oracle SQL to plot actual dates from Schedule Information?
我問了有關SQL Server的問題 ,但是Oracle環境(10g)的答案是什么?
如果我有一個表,其中包含表示特定日期的計划信息,是否可以編寫一條SQL語句,以使用MSSQL的“ Commom表表達式”之類的信息將該信息轉換為實際的行?
考慮帶有以下列的付款時間表表:
SchedID StartDate Term Frequency PaymentAmt ------------------------------------------------- 1 05-Jan-2003 48 12 1000.00 2 20-Dec-2008 42 6 25.00
是否有一條SQL語句可以讓我從上面轉到下面?
Running SchedID Payment Due Expected Num Date Total -------------------------------------- 1 1 05-Jan-2003 1000.00 1 2 05-Jan-2004 2000.00 1 3 05-Jan-2005 3000.00 1 4 05-Jan-2006 4000.00 2 1 20-Dec-2008 25.00 2 2 20-Jun-2009 50.00 2 3 20-Dec-2009 75.00 2 4 20-Jun-2010 100.00 2 5 20-Dec-2010 125.00 2 6 20-Jun-2011 150.00 2 7 20-Dec-2011 175.00
您的想法受到贊賞。
Oracle實際上具有使用CONNECT BY子句進行分層查詢的語法。 相比之下,SQL Server對WITH子句的使用看起來像是hack:
SELECT t.SchedId,
CASE LEVEL
WHEN 1 THEN
t.StartDate
ELSE
ADD_MONTHS(t.StartDate, t.frequency)
END 'DueDate',
CASE LEVEL
WHEN 1 THEN
t.PaymentAmt
ELSE
SUM(t.paymentAmt)
END 'RunningExpectedTotal'
FROM PaymentScheduleTable t
WHERE t.PaymentNum <= t.Term / t.Frequency
CONNECT BY PRIOR t.startdate = t.startdate
GROUP BY t.schedid, t.startdate, t.frequency, t.paymentamt
ORDER BY t.SchedId, t.PaymentNum
我不是100%的人-我對使用以下內容更有信心:
SELECT t.SchedId,
t.StartDate 'DueDate',
t.PaymentAmt 'RunningExpectedTotal'
FROM PaymentScheduleTable t
WHERE t.PaymentNum <= t.Term / t.Frequency
CONNECT BY PRIOR t.startdate = t.startdate
ORDER BY t.SchedId, t.PaymentNum
...但是它不包含處理鏈中第二個以上條目以增加月份和總和的邏輯。 可以使用GROUP BY CUBE或ROLLUP進行求和,具體取決於所需的細節。
我不明白為什么schedid = 1需要5個付款日,scheid = 2需要7個付款日?
48/12 = 4和42/6 =7。因此,我預計schedid = 1需支付4天。
無論如何,我使用模型子句:
create table PaymentScheduleTable
( schedid number(10)
, startdate date
, term number(3)
, frequency number(3)
, paymentamt number(5)
);
insert into PaymentScheduleTable
values (1,to_date('05-01-2003','dd-mm-yyyy')
, 48
, 12
, 1000);
insert into PaymentScheduleTable
values (2,to_date('20-12-2008','dd-mm-yyyy')
, 42
, 6
, 25);
commit;
現在選擇帶模型子句:
select schedid, to_char(duedate,'dd-mm-yyyy') duedate, expected, i paymentnum
from paymentscheduletable
model
partition by (schedid)
dimension by (1 i)
measures (
startdate duedate
, paymentamt expected
, term
, frequency)
rules
( expected[for i from 1 to term[1]/frequency[1] increment 1]
= nvl(expected[cv()-1],0) + expected[1]
, duedate[for i from 1 to term[1]/frequency[1] increment 1]
= add_months(duedate[1], (cv(i)-1) * frequency[1])
)
order by schedid,i;
輸出:
SCHEDID DUEDATE EXPECTED PAYMENTNUM
---------- ---------- ---------- ----------
1 05-01-2003 1000 1
1 05-01-2004 2000 2
1 05-01-2005 3000 3
1 05-01-2006 4000 4
2 20-12-2008 25 1
2 20-06-2009 50 2
2 20-12-2009 75 3
2 20-06-2010 100 4
2 20-12-2010 125 5
2 20-06-2011 150 6
2 20-12-2011 175 7
11 rows selected.
我沒有打算回答自己的問題,但是我現在正在與Oracle一起工作,我不得不學習一些新的Oracle風格的東西。
無論如何,CONNECT BY語句確實非常好-是的,比MSSQL的層次查詢方法好得多,並且使用該構造,我能夠生成一個非常干凈的查詢,該查詢可以滿足我的要求:
SELECT DISTINCT
t.SchedID
,level as PaymentNum
,add_months(T.StartDate,level - 1) as DueDate
,(level * t.PaymentAmt) as RunningTotal
FROM SchedTest t
CONNECT BY level <= (t.Term / t.Frequency)
ORDER BY t.SchedID, level
我唯一剩下的問題是我必須使用DISTINCT,因為我無法弄清楚如何從DUAL(和aff的單行Oracle表)中選擇行,而不是從計划數據表中選擇行,該表至少有兩行。 如果可以使用FROM DUAL進行上述操作,則不需要DISTINCT指示器。 有什么想法嗎?
除此之外,我認為這還不錯。 嗯?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.