2012-11-02 75 views
0

我有一個表用3倍柱TSQL確定的價格趨勢

 
+---------------+-------------------------+-------+ 
| InstrumentId |   Date   | Price | 
+---------------+-------------------------+-------+ 
|   39 | 2012-10-31 00:00:00.000 | 150 | 
|   39 | 2012-11-01 00:00:00.000 | 160 | 
|   39 | 2012-11-01 00:00:00.000 | 200 | 
|   40 | 2012-10-31 00:00:00.000 | 150 | 
|   40 | 2012-11-01 00:00:00.000 | 140 | 
|   40 | 2012-11-01 00:00:00.000 | 200 | 
|   50 | 2012-10-31 00:00:00.000 | 150 | 
|   50 | 2012-11-01 00:00:00.000 | 150 | 
|   50 | 2012-11-01 00:00:00.000 | 150 | 
+---------------+-------------------------+-------+

我需要recive下一結果:

 
+--------------+-------+ 
| InstrumentId | Price | 
+--------------+-------+ 
|   39 | 200 | 
|   40 |  0 | 
|   50 | 150 | 
+--------------+-------+ 

規則: 如果價格相同InstrumentId生長或等於=>返回上一個價格(這意味着每個下一個價格大於或等於前一個價格 例如Id 39:150 < = 160 < = 200 => return 200) 如果同一InstrumentId的任何價格小於pr evious => return 0(see instrumentId 40)

我可以使用遊標來做到這一點...但我認爲存在一個簡單的解決方法來做到這一點。 任何想法?

測試數據:

DECLARE @table TABLE(
    instrumentId INT NOT NULL, 
    priceListDate DATETIME NOT NULL, 
    price DECIMAL NOT NULL 
) 

INSERT INTO @table 
(
    instrumentId, 
    priceListDate, 
    price 
) 
VALUES(39, '2012-10-31 00:00:00.000', 150), 
(39,'2012-11-01 00:00:00.000', 160), 
(39,'2012-11-01 00:00:00.000', 200), 
(40,'2012-10-31 00:00:00.000', 150), 
(40,'2012-11-01 00:00:00.000', 140), 
(40,'2012-11-01 00:00:00.000', 200), 
(50,'2012-10-31 00:00:00.000', 150), 
(50,'2012-11-01 00:00:00.000', 150), 
(50,'2012-11-01 00:00:00.000', 150) 

回答

3

讓我知道這是否工作正常。我猜你的桌子價格不會有-1的價格,我認爲這會給目前的解決方案帶來問題。

WITH CTE 
     AS (SELECT RN = ROW_NUMBER() OVER (ORDER BY instrumentId) , 
        * 
      FROM  @table 
     ) 
SELECT CASE WHEN MIN(X.xPrice) = -1 THEN 0 
      ELSE MAX(X.xPrice) 
     END 'price' , 
     X.instrumentId 
FROM (SELECT CASE WHEN [Current Row].instrumentId = [Next Row].instrumentId 
         THEN CASE WHEN [Current Row].price > [Next Row].price 
            THEN -1 
            ELSE [Current Row].price 
           END 
         ELSE CASE WHEN [Previous Row].instrumentId = [Current Row].instrumentId 
            THEN CASE WHEN [Previous Row].price <= [Current Row].price 
              THEN [Current Row].price 
              ELSE -1 
             END 
            ELSE [Current Row].price 
           END 
        END 'xPrice' , 
        [Current Row].RN , 
        [Current Row].instrumentId 
      FROM  CTE [Current Row] 
        LEFT JOIN CTE [Previous Row] ON [Previous Row].RN = [Current Row].RN 
                - 1 
        LEFT JOIN CTE [Next Row] ON [Next Row].RN = [Current Row].RN 
               + 1 
     ) X 
GROUP BY X.instrumentId 

它可能看起來有點令人費解,但其基本思想是,以確定爲了測試該行的價格列的值在當前的下一個和前行。

+0

非常感謝,它工作正常! – driver