2017-01-30 92 views
1

我有一張表格,其中只有貸款的記錄對應於它們被取出和償還的具體日期 - 即每筆貸款兩筆記錄。SQL在現有記錄之間插入行

Loans 

Loan ID | Month  | Rate | Action 
-------------------------------- 
1  | 5/1/2000 | 5.50% | New 
1  | 9/1/2000 | 6.00% | Closed 
2  | 3/1/2000 | 5.25% | New 
2  | 5/2/2000 | 5.50% | Closed 

我有另一個利率記錄每個日期。

Interest rates 

Month  | Rate 
-------------------- 
1/1/2000 | 5.00% 
2/1/2000 | 5.25% 
3/1/2000 | 5.25% 
4/1/2000 | 5.25% 
5/1/2000 | 5.50% 
6/1/2000 | 5.50% 
7/1/2000 | 5.50% 
8/1/2000 | 6.00% 
9/1/2000 | 6.00% 
10/1/2000 | 6.50% 

我想插入行對當給定貸款取出,歸還之間的貸款表丟失時間(和相應的利率)。鑑於中間日期需要插入的每一筆貸款,我一直沒能解決這個與LEFT JOIN,MERGE等

預期的結果:使硬

Loan ID | Month  | Rate | Action 
--------------------------------- 
1  | 5/1/2000 | 5.50% | New 
1  | 6/1/2000 | 5.50% | NULL 
1  | 7/1/2000 | 5.50% | NULL 
1  | 8/1/2000 | 6% | NULL 
1  | 9/1/2000 | 6% | Closed 
2  | 3/1/2000 | 5.25% | New 
2  | 4/1/2000 | 5.25% | NULL 
2  | 5/1/2000 | 5.50% | Closed 
+5

請顯示一些示例數據,預期輸出並標記您正在使用的數據庫。 –

+0

通過改進格式問題更具可讀性。我改變了一些用戶的解釋,我認爲它更有意義。 – McNets

回答

0

Numbers表格往往是有幫助的,當你需要生成日期序列行。它只是一個包含大量整數序列的表格。你可以閱讀如何創建一個here(以及其他地方)。一旦你在的地方,你可以使用這樣的查詢(這是SQL Server):

;with cteLoan as(
select t1.LoanID, min(t1.Month) StartDate, max(t1.Month) EndDate 
from Table1 t1 
group by t1.LoanID 
) 

select c.LoanID, dateadd(month, n.Number, c.StartDate) Month, t2.Rate, null Action 
from Numbers n 
cross join cteLoan c 
join Table2 t2 on t2.Month = dateadd(month, n.Number, c.StartDate) 
where n.Number >= 0 and n.number < DATEDIFF(month, c.StartDate, c.EndDate) 

union 

select t1.LoanID, t1.Month, t1.Rate, t1.Action 
from Table1 t1 
order by LoanID, Month 

要結果插入另一張表,你應該能夠做到:

insert into Results(LoadID, Month, Rate, Action) 
select c.LoanID, dateadd(month, n.Number, c.StartDate) Month, t2.Rate, null Action 
from Numbers n 
cross join cteLoan c 
join Table2 t2 on t2.Month = dateadd(month, n.Number, c.StartDate) 
where n.Number >= 0 and n.number < DATEDIFF(month, c.StartDate, c.EndDate) 

union 

select t1.LoanID, t1.Month, t1.Rate, t1.Action 
from Table1 t1 
order by LoanID, Month 
+0

Jerrad,你的建議奏效 - 謝謝!但我無法將輸出保存爲永久表格。您能否請告知在何處放置「SELECT * INTO ...」子句?謝謝。 –

+0

我已經更新了答案。 – Jerrad

+0

我試過上面的,但我得到以下錯誤:消息208,級別16,狀態1,行2 無效的對象名稱'結果'。我是否需要先創建一個名爲Results的表? –

0

您的設計和你沒有說你正在使用什麼數據庫。下面是SQL Server中的樣品(查詢也將PostgreSQL的工作):

DECLARE @loans TABLE 
    (
     LoanID INT , 
     [Month] DATETIME , 
     Rate DECIMAL(4, 2) , 
     [Action] VARCHAR(10) 
    ); 

INSERT @loans 
     (LoanID, Month, Rate, Action) 
VALUES (1, '5/1/2000', 5.50, 'New '), 
     (1, '9/1/2000', 6.00, 'Closed '), 
     (2, '3/1/2000', 5.25, 'New '), 
     (2, '5/2/2000', 5.50, 'Closed '); 


DECLARE @rates TABLE 
    (
     Month DATETIME , 
     Rate DECIMAL(4, 2) 
    ); 
INSERT @rates 
     (Month, Rate) 
VALUES ('1/1/2000', 5.00), 
     ('2/1/2000', 5.25), 
     ('3/1/2000', 5.25), 
     ('4/1/2000', 5.25), 
     ('5/1/2000', 5.50), 
     ('6/1/2000', 5.50), 
     ('7/1/2000', 5.50), 
     ('8/1/2000', 6.00), 
     ('9/1/2000', 6.00), 
     ('10/1/2000', 6.50); 

WITH loanStart 
      AS (SELECT * 
       FROM  @loans 
       WHERE Action = 'New' 
      ), 
     loanEnd 
      AS (SELECT * 
       FROM  @loans 
       WHERE Action = 'Closed' 
      ), 
     loanRanges (loanId, lStart, lEnd) 
      AS (SELECT ls.LoanID , 
         ls.Month , 
         le.Month 
       FROM  loanStart ls 
         INNER JOIN loanEnd le ON ls.LoanID = le.LoanID 
      ) 
    SELECT lr.loanId , 
      r.Month , 
      r.Rate , 
      COALESCE(ls.Action, le.Action) AS action 
    FROM @rates r 
      INNER JOIN loanRanges lr ON r.Month >= lr.lStart 
             AND r.Month <= lr.lEnd 
      LEFT JOIN loanStart ls ON ls.LoanID = lr.loanId 
             AND YEAR(ls.Month) = YEAR(r.Month) 
             AND MONTH(ls.Month) = MONTH(r.Month) 
      LEFT JOIN loanEnd le ON le.LoanID = lr.loanId 
            AND YEAR(le.Month) = YEAR(r.Month) 
            AND MONTH(le.Month) = MONTH(r.Month) 
    ORDER BY lr.loanId , 
      r.Month;