2017-10-10 16 views
0

カーソルを使用して顧客契約の日付レコードをループして、顧客がその契約内にあったすべての月/年のリストを作成したいと考えています。私はカーソルが正しい解決策であるかどうかも分かりません。しかし、それはとにかくここにあります!カーソルの話題は私にとってかなり新しいものです。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 
関連する問題