2016-07-06 6 views
1

SQL Server 2014をメインのレポートデータベースとして使用しており、非常に特殊なデータ操作が必要なレポートがあります。私たちが処理しなければならないデータは、さまざまな種類のシリーズ(四半期、半年次、年次など)で表示できる元本と利息の支払いのスケジュールです。毎月の収入を決定するために、これらの元本および利息の支払いは、元の書式から月次スケジュールに再編成する必要があります。四半期および半期のプリンシパルおよび利払いを毎月の値に変換するSQL Server照会

理想のキャッシュフローのスケジュール

 
Cashflow_Date  Principal  Interest 
-------------  ---------  -------- 
2015-12-15  0    166.667 
2016-01-15  0    166.667 
2016-02-15  0    166.667 
2016-03-15  0    166.667 
2016-04-15  0    166.667 
2016-05-15  0    166.667 
2016-06-15  0    166.667 
2016-07-15  0    166.667 
2016-08-15  0    166.667 
2016-09-15  0    166.667 
2016-10-15  0    166.667 
2016-11-15  0    166.667 
2016-12-15  10000.00  1000.00 

を:

オリジナルキャッシュフローのスケジュール以下

 
Cashflow_Date  Principal  Interest 
-------------  ---------  -------- 
2015-12-15  0    1000.00 
2016-06-15  0    1000.00 
2016-12-15  10000.00  1000.00 

必要とされている形式は次のとおりです。以下は、元のデータフォーマットの一例です基本的には、元のスケジュールからの支払いの月間は元の支払い日とともに返品される必要があります。元の支払いは元の支払い日(つまり、 1000/6 = 166.667/2015-12-15から2016-05-15)。最後の支払い日(この場合は2016-12-15)はそのままです。元本と利息の支払いは、当初のスケジュール全体で同じであることが保証されていないため、適切に支払いを分割することが重要です。

残念なことに、私たちは残念ながらカーソル内でカーソルとループを使用しています(私が知っていると非常に悪いことです)。同じ結果をより迅速に生成できるセットベースのクエリに誰もが洞察力を提供できますか?どんな支援も大歓迎です。

更新シナリオ下の投稿質問パー

、1時間の元本または利息の支払いが元のスケジュールで行われた場合、それらの支払いはそれに応じて分割されています。あなたはおそらく

エッジケース希望のキャッシュフローのスケジュール

 
Cashflow_Date  Principal  Interest 
-------------  ---------  -------- 
2015-12-15  0    166.667 
2016-01-15  0    166.667 
2016-02-15  0    166.667 
2016-03-15  0    166.667 
2016-04-15  0    166.667 
2016-05-15  0    166.667 
2016-06-15  208.33  166.667 
2016-07-15  208.33  166.667 
2016-08-15  208.33  166.667 
2016-09-15  208.33  166.667 
2016-10-15  208.33  166.667 
2016-11-15  208.33  166.667 
2016-12-15  10000.00  1000.00 
+0

を参照してください。プリンシパルのみの支払いを処理しますか?これらのエッジケースや不規則なケースに対して期待される出力を表示できますか? – objectNotFound

+0

うれしい。指定した場合は、元の支払いに続く月間に次回の支払いまでに支払いを分割する必要があります。たとえば、2015年6月15日に元本が1250ドルで支払われた場合、その月および次の予定支払月までの毎月に元の1250ドルの一部が返されます(2016年までの元本支払いは208.33ドル/ 12-15)。 – user6554159

+0

質問を編集して表形式で表現してください。 – objectNotFound

答えて

0

:例えば1時間元本の支払いが2016年6月15日に行われた場合、その後、毎月の収入のスケジュールはこのようにそれを反映することになりますあなたは、あなただけの月の数に基づいて元本と利息を平均化する必要があり、最初の日と次の日までの日付を記入する集計テーブルのいくつかの並べ替えが必要

DECLARE @ TABLE (Cashflow_Date DATE, Principal DECIMAL (10,2), Interest DECIMAL (10,2)); 
INSERT @ VALUES ('2015-12-15', 0, 1000.0), ('2016-06-15', 1250.0, 1000.0), ('2016-12-15', 10000.0, 1000.0); 

SELECT DATEADD(MONTH, n.number, Cashflow_Date) Dates 
    , MAX(Principal)/ISNULL(DATEDIFF(MONTH, Cashflow_Date, nextDate), 1) Principal 
    , MAX(Interest)/ISNULL(DATEDIFF(MONTH, Cashflow_Date, nextDate), 1) Interest 
FROM (
    SELECT t.Cashflow_Date 
     , t.Principal 
     , t.Interest 
     , X.nextDate 
    FROM @ t 
    OUTER APPLY (
     SELECT MIN(Cashflow_Date) 
     FROM @ 
     WHERE Cashflow_Date > t.Cashflow_Date) X(nextDate)) t 
CROSS JOIN (
    SELECT number 
    FROM master..spt_values 
    WHERE type='P') n 
WHERE n.number < ISNULL(DATEDIFF(MONTH, Cashflow_Date, nextDate), 1) 
GROUP BY DATEADD(MONTH, n.number, Cashflow_Date), nextDate, Cashflow_Date 
ORDER BY DATEADD(MONTH, n.number, Cashflow_Date); 

:このような何かをしたいです最初の日付と次の日付の間のsです。

+0

それは素晴らしいです!ありがとう! – user6554159

0

これはあなたがカーソル

を取り除くに向けて始めるのに役立つならば、一度、通常の支払いが行われ、また、どのように私たちはしているときに何が起こるか(全てのシナリオを試験していない)

/* 
one time setup 

CREATE TABLE [dbo].[Tbl] 
(
    [cf] [date] NOT NULL, 
    [pmt] [int] NOT NULL, 
    [intrest] [int] NOT NULL 
) 
GO 

insert into dbo.Tbl values ('2015-12-15', 0 , 1000) 
insert into dbo.Tbl values ('2015-06-15', 0 , 1000) 
insert into dbo.Tbl values ('2016-12-15', 1000 , 1000) 

*/ 


select Top 13 b.* , intrest/6.0 as int_mnthly, DATEADD(Month,Mnth, cf) as cf_mnthly 
from dbo.Tbl b 
cross join 
( 
    select 1 as Mnth Union ALL 
    select 2 as Mnth Union ALL 
    select 3 as Mnth Union ALL 
    select 4 as Mnth Union ALL 
    select 5 as Mnth Union ALL 
    select 6 as Mnth 
) a 
order by cf_mnthly 
関連する問題