Please start any new threads on our new
site at https://forums.sqlteam.com. We've got lots of great SQL Server
experts to answer whatever question you can come up with.
Author |
Topic |
rogerclerkwell
Yak Posting Veteran
85 Posts |
Posted - 2011-06-24 : 09:51:34
|
I have a currency table and I want to create a view that lists for every date a currency rate.For example in the table is:CurrCode,CurrDate,CurrRateEUR 22-Jan-11 1.20EUR 19-Feb-11 1.17EUR 19-Mar-11 1.15EUR 16-Apr-11 1.16EUR 14-May-11 1.10EUR 11-Jun-11 1.12HKD 22-Jan-11 12.55HKD 19-Feb-11 13.00HKD 19-Mar-11 12.57HKD 16-Apr-11 12.53HKD 14-May-11 12.43HKD 11-Jun-11 12.54I want it to become:EUR 22-Jan-11 1.20EUR 23-Jan-11 1.20EUR 24-Jan-11 1.20EUR 25-Jan-11 1.20EUR 26-Jan-11 1.20EUR 27-Jan-11 1.20EUR 28-Jan-11 1.20EUR 29-Jan-11 1.20EUR 30-Jan-11 1.20EUR 31-Jan-11 1.20until next rate EUR 19-Feb-11 1.17 an so on...Is this possible to do?Thanks.Script to create table:CREATE TABLE [CurrencyExchangeRates]([CurrCode] [varchar](10) NOT NULL,[CurDate] [datetime] NOT NULL,[CurrRate] [decimal](38, 20) NOT NULL);INSERT INTO CurrencyExchangeRates VALUES ('EUR','22-Jan-11','1.2');INSERT INTO CurrencyExchangeRates VALUES ('EUR','19-Feb-11','1.17');INSERT INTO CurrencyExchangeRates VALUES ('EUR','19-Mar-11','1.15');INSERT INTO CurrencyExchangeRates VALUES ('EUR','16-Apr-11','1.16');INSERT INTO CurrencyExchangeRates VALUES ('EUR','14-May-11','1.1');INSERT INTO CurrencyExchangeRates VALUES ('EUR','11-Jun-11','1.1182');INSERT INTO CurrencyExchangeRates VALUES ('HKD','22-Jan-11','12.55');INSERT INTO CurrencyExchangeRates VALUES ('HKD','19-Feb-11','13');INSERT INTO CurrencyExchangeRates VALUES ('HKD','19-Mar-11','12.57');INSERT INTO CurrencyExchangeRates VALUES ('HKD','16-Apr-11','12.53');INSERT INTO CurrencyExchangeRates VALUES ('HKD','14-May-11','12.43');INSERT INTO CurrencyExchangeRates VALUES ('HKD','11-Jun-11','12.54'); |
|
Lamprey
Master Smack Fu Yak Hacker
4614 Posts |
Posted - 2011-06-24 : 11:12:40
|
Here is one way:;WITH Tens (N) AS (SELECT 0 UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9), Thousands(N) AS (SELECT t1.N FROM Tens t1 CROSS JOIN Tens t2 CROSS JOIN Tens t3), Millions (N) AS (SELECT t1.N FROM Thousands t1 CROSS JOIN Thousands t2), Tally (N) AS (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 0)) FROM Millions),Rate AS ( SELECT *, DATEDIFF(DAY, 0, CurDate) AS DayNum, ROW_NUMBER() OVER(PARTITION BY CurrCode ORDER BY CurDate) AS RowNum FROM CurrencyExchangeRates)SELECT D.CurrCode, D.CurrRate, DATEADD(DAY, T.N, 0) AS CurdateFROM ( -- Get Day Range SELECT A.CurrCode, A.CurrRate, A.DayNum AS StartDayNum, COALESCE(B.DayNum, A.DayNum) AS EndDayNum FROM Rate AS A LEFT OUTER JOIN Rate AS B ON A.CurrCode = B.CurrCode AND A.RowNum + 1 = B.RowNum ) AS DINNER JOIN Tally AS T ON T.N BETWEEN D.StartDayNum AND D.EndDayNum ORDER BY D.CurrCode, DATEADD(DAY, T.N, 0) |
 |
|
rogerclerkwell
Yak Posting Veteran
85 Posts |
Posted - 2011-06-24 : 12:03:39
|
Wow Lamprey this looks great I'll give it a go. |
 |
|
rogerclerkwell
Yak Posting Veteran
85 Posts |
Posted - 2011-06-24 : 12:30:45
|
Hi Lamprey, Works great except for when there is a date change it has 2 exchange rates on one day eg 19-MAR-11, is ti possible to not have the entry EUR 1.17 19-Mar-11 and only show the new EUR 1.15 19-Mar-11, apart from that the code is fantastic.:EUR 1.17 16-Mar-11EUR 1.17 17-Mar-11EUR 1.17 18-Mar-11EUR 1.17 19-Mar-11EUR 1.15 19-Mar-11EUR 1.15 20-Mar-11EUR 1.15 21-Mar-11EUR 1.15 22-Mar-11 |
 |
|
Lamprey
Master Smack Fu Yak Hacker
4614 Posts |
Posted - 2011-06-24 : 12:45:19
|
It can be done. But, how to determine which to pick? Is there another column that we can use to determine the order/winner? |
 |
|
rogerclerkwell
Yak Posting Veteran
85 Posts |
Posted - 2011-06-24 : 13:50:50
|
Hi Lamprey,No sorry I haven't got any other columns in the table... can the code see maybe the MIN(next currency date) and ignore this eg removing the 19-MAR-11 for 1.17 because there is a 19-MAR-11 1.15?Sorry I'm not much help my SQL skills are really quite basic. |
 |
|
Lamprey
Master Smack Fu Yak Hacker
4614 Posts |
Posted - 2011-06-24 : 14:12:10
|
It could pick the MIN value, but that doesn't seem right to me. Couldn't the rate go up instead?If you want to use the MIN I think you just need to make a small change to the Rate3 CTE:Rate AS ( SELECT CurrCode, CurDate, MIN(CurrRate) AS CurrRate, DATEDIFF(DAY, 0, CurDate) AS DayNum, ROW_NUMBER() OVER(PARTITION BY CurrCode ORDER BY CurDate) AS RowNum FROM CurrencyExchangeRates GROUP BY CurrCode, CurDate) |
 |
|
rogerclerkwell
Yak Posting Veteran
85 Posts |
Posted - 2011-06-25 : 04:14:43
|
Hmmm yeah see what you mean using MIN might not be 100% right, I'll try the code above and see what I get. Thanks. |
 |
|
|
|
|
|
|