2017-10-10 67 views
0

我正在尋找使用遊標來遍歷某些客戶合同日期記錄以生成客戶在該合同中所有月份/年份的列表。我甚至不確定一個光標是否是正確的solutuion ..但是,無論如何它都是!光標對我來說是相當新的。SQL遊標使用

我的數據存儲如下;

ContractStartDate ContractEndDate CustomerID Country 
01-10-2016   01-02-2017  1234   UK 
01-12-2016   01-03-2017  5678   UK 

而我正在尋找顯示如下;

Customer Country Month Year 
1234  UK  Oct  2016 
1234  UK  Nov  2016 
1234  UK  Dec  2016 
1234  UK  Jan  2017 
1234  UK  Feb  2017 
5678  UK  Dec  2016 
5678  UK  Jan  2017 
5678  UK  Feb  2017 
5678  UK  Mar  2017 

腳本至今爲止;

DECLARE 

@StartDate DATETIME, 
@EndDate DATETIME, 
@Customer nvarchar(30), 
@Country nvarchar(30), 
@Cursor  as CURSOR; 

SET @Cursor = CURSOR FOR 
SELECT DISTINCT f.ContractStartDate, f.ContractEndDate, c.Customer, c.Country 
FROM Contracts c 
    JOIN CustomerInfo i 
     ON c.CustomerID = i.ID 

OPEN @Cursor 
FETCH NEXT FROM @Cursor INTO @StartDate,@EndDate,@Customer,@Country;  

WHILE @@FETCH_STATUS = 0 
BEGIN 


SELECT DATENAME(MONTH, DATEADD(MONTH, x.number, @StartDate)) AS MonthName, DATENAME(YEAR, DATEADD(MONTH, x.number, @StartDate)) AS MonthName 
FROM master.dbo.spt_values x 
WHERE x.type = 'P'   
AND  x.number <= DATEDIFF(MONTH, @StartDate, @EndDate); 

END 

Close @Cursor 
DEALLOCATE @Cursor 
+0

看起來像SQLServer,請添加必要的標籤,不同的引擎有不同的光標處理。 – bummi

+0

合同開始/結束日期是否始終在本月的第一天? – TZHX

+0

日期並不總是在開始/結束。 (現在也編輯標籤,謝謝) – user2261755

回答

0

如果你對使用光標沒有心設置,這是一種不同的方法。

我已經設置了參考日曆,加入了您的數據,並返回了開始/結束日期之間的所有內容。 我已經做到了這一點的限制是,有一個2048個月的最大範圍(我限制在這裏600)。如果你需要更多,那麼有辦法克服這個限制。

-- Set up for testing 

create table test.contracts(
    ContractStartDate datetime, ContractEndDate datetime, CustomerID int ,Country nvarchar(2) 
) 

insert into test.contracts(ContractStartDate,ContractEndDate,CustomerID,Country) 
Values(convert(datetime,'2016-10-01'), CONVERT(datetime,'2017-02-01'), 1234, 'UK') 
insert into test.contracts(ContractStartDate,ContractEndDate,CustomerID,Country) 
Values(convert(datetime,'2016-12-01'), CONVERT(datetime,'2017-03-01'), 5678, 'UK') 

-- Execute 
SELECT 
    C.*, cal.[Month] 
FROM test.contracts C 
     INNER JOIN 
    (
     SELECT dateadd(m,number,convert(datetime,'2000-01-01')) as [Month] 
     FROM master..[spt_values] 
     where type='p' and number BETWEEN 0 AND 600 
    ) as cal 
    ON C.ContractStartDate <= cal.Month and C.ContractEndDate >= cal.Month