J'ai les lignes suivantes à partir d'une table dans SQL Server 2008 R2
+-------------------------------------------+ | ID EntryType dt price | +-------------------------------------------+ | 14 4 2012-11-07 0.025000 | | 16 5 2012-11-07 0.026000 | | 18 6 2012-11-07 0.026000 | | 20 7 2012-11-07 0.026000 | +-------------------------------------------+
Ce que je voudrais faire est de répartir les lignes en fonction du EntryType (le EntryType ne change pas)
For EntryType = 4 (1 row) For EntryType = 5 (2 row) For EntryType = 6 (3 row) For EntryType = 7 (9 row)
et le champ dt sera incrémenté (dans un intervalle de mois), de sorte que la sortie ressemble à ceci:
+-----------+-----------+-------+ | EntryType | dt | Price | +-----------+-----------+-------+ | 4 | 11/7/2012 | 0.024 | | 5 | 12/7/2012 | 0.025 | | 5 | 1/7/2013 | 0.025 | | 6 | 2/7/2013 | 0.026 | | 6 | 3/7/2013 | 0.026 | | 6 | 4/7/2013 | 0.026 | | 7 | 5/7/2013 | 0.027 | | 7 | 6/7/2013 | 0.027 | | 7 | 7/7/2013 | 0.027 | | 7 | 8/7/2013 | 0.027 | | 7 | 9/7/2013 | 0.027 | | 7 | 10/7/2013 | 0.027 | | 7 | 11/7/2013 | 0.027 | | 7 | 12/7/2013 | 0.027 | | 7 | 1/7/2014 | 0.027 | +-----------+-----------+-------+
Est-ce possible avec CTE et SQL?
Voici un moyen de le faire dans un CTE récursif :
;with RecordCounts as ( -- Establish row counts for each EntryType select 4 as EntryType, 1 as RecordCount union all select 5, 2 union all select 6, 3 union all select 7, 9 ), PricesCte as ( -- Get initial set of records select ID, p.EntryType, (select min(dt) from MyTable) as dt, price, 1 as RecordNum from MyTable p join RecordCounts c on p.EntryType = c.EntryType -- Only get rows where we've established a RecordCount -- Add records recursively according to RecordCount union all select ID, p.EntryType, dt, price, RecordNum + 1 from PricesCte p join RecordCounts c on p.EntryType = c.EntryType where RecordNum + 1 <= c.RecordCount ) select EntryType, dateadd(mm, row_number() over (order by EntryType, ID) - 1, dt) as dt, price from PricesCTE order by EntryType option (maxrecursion 0) -- Infinite recursion, default limit is 100
Voici le SqlFiddle montrant ce travail.
Un certain nombre de choses:
;WITH e (ID, EntryType, row, dt, Price, [Len]) AS ( SELECT ID, EntryType, CASE EntryType WHEN 4 THEN 1 WHEN 5 THEN 2 WHEN 6 THEN 3 WHEN 7 THEN 9 END AS row, dt, Price, 0 AS [Len] FROM dbo.your_table ), x (ID, EntryType, row, dt, Price, [Len]) AS ( SELECT ID, EntryType, row, dt, Price, 1 FROM e UNION ALL SELECT e.ID, e.EntryType, e.row, e.dt, e.Price, x.[Len] + 1 FROM e , x WHERE e.ID = x.ID AND e.row > x.[Len] ) SELECT EntryType, DATEADD(mm, ROW_NUMBER() OVER(ORDER BY EntryType)-1, dt) AS dt, Price FROM x ORDER BY EntryType
La seule chose que je ne peux pas comprendre par quels critères pour recevoir le prix?
Démo sur SQL Fiddle
Je ne sais pas si cela peut être fait par CTE, car je ne peux pas dire de logique entre EntryType et # of row.
Pour la question, je pense qu'il est plus facile de build une table temporaire avec le nombre de lignes que vous voulez
DECLARE @Entry TABLE(EntryType INT, seq INT) INSERT INTO @Entry (EntryType , seq) VALUES (4,1) ,(5,1) ,(5,2) ,(6,1) ... ,(7,1) .. ,(7,9)
Après cela, une simple requête obtiendra le même résultat
SELECT t.EntryType , DATEADD(MONTH,e.seq, t.dt) as dt,t.Price FROM YourTable t INNER JOIN @Entry e ON t.EntryType = e.EntryType