2

我從一個表中的SQL Server以下行2008 R2分離行使用CTE

+-------------------------------------------+ 
| 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 | 
+-------------------------------------------+ 

我希望做的是普及基礎上,EntryType行(該EntryType不會改變)

For EntryType = 4 (1 row) 
For EntryType = 5 (2 row) 
For EntryType = 6 (3 row) 
For EntryType = 7 (9 row) 

和dt的字段將被遞增(在一個月的間隔),所以輸出看起來像這樣:

+-----------+-----------+-------+ 
| 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 | 
+-----------+-----------+-------+ 

用CTE和SQL可以做到這一點嗎?

+1

演示? – Bridge

+0

我應該提到它。 SQL Server – kadourah

+0

我不認爲我理解這個...... :) – codingbiz

回答

3

這裏一種方法可以做到這一點的recursive CTE

;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 

下面是SqlFiddle顯示這項工作。

幾件事情:

  • 我認爲,作爲記錄的數量將上升,這可能會表現的更好使用Tally table而不是遞歸繁殖記錄。您將與Tally表交叉連接,並使where子句根據RecordCount限制記錄
  • 我不明白定價應如何從輸入更改爲輸出。
  • 我不知道你在哪裏爲每個EntryType建立RecordCount,所以我將它添加到另一個CTE中。
+0

+1我不明白如何收到價格太;) –

1

不知道這是否可以由CTE完成,因爲我無法告訴EntryType和#行之間的任何邏輯。

對於這個問題,我覺得它更容易只是建立一個臨時表的行數你想

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) 

之後,一個簡單的查詢將得到同樣的結果

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 
2
;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 

我不能用什麼標準理解唯一接受的價格?

SQL Fiddle您正在使用哪個RDBMS

+0

幾乎相同的事情,很好! –