我有一个包含3列的表
+---------------+-------------------------+-------+ | 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 | +---------------+-------------------------+-------+
我需要回顾下一个结果:
+--------------+-------+ | InstrumentId | Price | +--------------+-------+ | 39 | 200 | | 40 | 0 | | 50 | 150 | +--------------+-------+
规则: 如果同一InstrumentId的价格正在增长或相等=>返回最后价格(这意味着每个下一个价格大于或等于之前的价格。 例如Id 39:150< = 160< = 200 =>返回200) 如果同一InstrumentId的任何价格低于previous =>返回0(见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)
答案 0 :(得分: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
看起来有点复杂,但基本思路是确定当前打开的下一行和上一行,以便测试该行的价格列的值。