我的货币汇率表的格式与以下类似:
asofdate currency spot fwd1m fwdyield rank_
1999-03-26 00:00:00.000 EUR 0.93161900 0.93340000 1.001911725716199433459 1
1999-03-26 00:00:00.000 NOK 7.80300000 7.81630000 1.001704472638728694092 2
1999-03-26 00:00:00.000 CAD 1.51350000 1.51355000 1.000033036009250082590 3
1999-03-26 00:00:00.000 AUD 1.57728700 1.57713800 0.999905533996032427833 4
1999-03-26 00:00:00.000 NZD 1.86828600 1.86748300 0.999570194285029165770 5
1999-03-26 00:00:00.000 GBP 0.61728400 0.61665000 0.998972920082166393426 6
1999-03-26 00:00:00.000 SEK 8.33400000 8.32080000 0.998416126709863210943 7
1999-03-26 00:00:00.000 CHF 1.48480000 1.48007000 0.996814385775862068965 8
1999-03-26 00:00:00.000 JPY 120.09000000 119.60550000 0.995965525855608293779 9
1999-05-26 00:00:00.000 EUR 0.95438100 0.95662000 1.002346023233907632276 1
1999-05-26 00:00:00.000 NOK 7.85100000 7.86505000 1.001789580945102534708 2
1999-05-26 00:00:00.000 AUD 1.54154500 1.54147300 0.999953293611279592875 3
1999-05-26 00:00:00.000 CAD 1.47330000 1.47307000 0.999843887870766306930 4
从这张表中,我想保留每个日期的排名(基于fwdyield字段)的TOP和BOTTOM 3记录。
输出看起来像这样,但会包括初始表中的每个日期:
asofdate currency spot fwd1m fwdyield pos
1999-03-26 00:00:00.000 JPY 120.09000000 119.60550000 0.995965525855608293779 -1
1999-03-26 00:00:00.000 CHF 1.48480000 1.48007000 0.996814385775862068965 -1
1999-03-26 00:00:00.000 SEK 8.33400000 8.32080000 0.998416126709863210943 -1
1999-03-26 00:00:00.000 CAD 1.51350000 1.51355000 1.000033036009250082590 1
1999-03-26 00:00:00.000 NOK 7.80300000 7.81630000 1.001704472638728694092 1
1999-03-26 00:00:00.000 EUR 0.93161900 0.93340000 1.001911725716199433459 1
挑战在于为每个日期执行此操作,以避免需要使用循环/游标。思考?
答案 0 :(得分:2)
这可以通过使用一些OLAP函数来完成:
SELECT * -- only for the example, because I don't know what you need
FROM (SELECT a.*, ROW_NUMBER() OVER(PARTITION BY CAST(asOfDate as DATE)
ORDER BY fwdyield ASC) as ascRank,
ROW_NUMBER() OVER(PARTITION BY CAST(asOfDate as DATE)
ORDER BY fwdyield DESC) as descRank
FROM Exchange a) b
WHERE ascRank < 4
OR descRank < 4
从样本数据中得到以下结果:
ASOFDATE CURRENCY SPOT FWD1M FWDYIELD RANK ASCRANK DESCRANK
March, 26 1999 00:00:00+0000 EUR 0.931618988514 0.9333999753 1.001911759377 1 9 1
March, 26 1999 00:00:00+0000 NOK 7.802999973297 7.816299915314 1.001704454422 2 8 2
March, 26 1999 00:00:00+0000 CAD 1.513499975204 1.513550043106 1.000033020973 3 7 3
March, 26 1999 00:00:00+0000 SEK 8.333999633789 8.320799827576 0.998416125774 7 3 7
March, 26 1999 00:00:00+0000 CHF 1.484799981117 1.480069994926 0.996814370155 8 2 8
March, 26 1999 00:00:00+0000 JPY 120.089996337891 119.605499267578 0.995965540409 9 1 9
May, 26 1999 00:00:00+0000 EUR 0.954380989075 0.956619977951 1.002346038818 1 4 1
May, 26 1999 00:00:00+0000 NOK 7.850999832153 7.86504983902 1.001789569855 2 3 2
May, 26 1999 00:00:00+0000 AUD 1.541545033455 1.541473031044 0.999953269958 3 2 3
May, 26 1999 00:00:00+0000 CAD 1.473299980164 1.473070025444 0.999843895435 4 1 4
但这里有几个问题:
asOfDate
是时间戳(SQL Server DATETIME
或DATETIME2
),因此需要进行转换/转换。这意味着它(可能)无法使用索引。我假设这应该是“工作日”。 (或类似的),所以将其转换为DATE
类型应该没问题(也许应该这样做,因为域名原因)。fwd...
代表什么?(作为旁注,我注意到原始rank
列与descRank
匹配 - 如果已存储,则显然可以删除该特定计算列。)