2017-02-20 83 views
1

我有一張桌子,上面有不同貨幣的交易,其中一些日期屬於週末或假期。例如:如何參加週末或節假日的最新匯率日期?

Date  currency_code ammount 
20-02-2017 EUR    55 
18-02-2017 GBP    33 
17-02-2017 EUR    44.55 

什麼我Currency表看起來像一個例子:

SELECT rate,date, currency_code FROM exchangeTable: 

rate  Date   currency_code 
53,35  13-02-2017 ADP 
53,35  14-02-2017 ADP  
182,4  16-02-2017 ADP  
192,45 17-02-2017 ADP  
191,31 20-02-2017 ADP 

有一個簡單的子查詢我可以在我加入語句中使用,這將加入最新的貨幣日期到我的交易日,如果它在週末或假期?我想我應該在這裏使用分區,但是沒有太多經驗。

left join (?????????) a on a.date = b.date and a.currency_code= b.currency_code 
+0

您是否試過在最後包含'WHERE'子句?就像'WHERE a.Date = b.Date'? – David

+0

替換???????用GROUP BY查詢。 – jarlh

回答

0

首先,你需要JOIN所有行形成Currency表相同CurrencyCode,那麼你可以使用RANK() PARTITION (...功能,選擇一個與最近的日期相比,交易的日期。

SELECT 
    * 
FROM 
    (SELECT 
     t.*, 
     c.*, 
     RANK() OVER (PARTITION BY t.ID ORDER BY ABS(DATEDIFF(d, t.[Date], c.[Date])) ASC, c.[Date] DESC) rn 
    FROM 
     Transactions t 
    INNER JOIN 
     Currency c ON t.CurrencyCode = c.CurrencyCode) t 
WHERE 
    t.rn = 1 
0

您可以使用派生表ROW_NUMBER和分區來解決此問題。這樣做可以消除使用DATEPART函數和dw(星期幾)參數的週末來忽略任何週六和週日。對於假期,你必須有假期日期表,因爲假期完全是主觀的。

ROW_NUMBER允許您獲得給定自定義排序和分區的行號索引。我們按貨幣進行分割,因此每次我們點擊一​​種新貨幣時索引都會重置,我們按DATE DESC訂購,因此每種貨幣的最近日期爲1

-- create a sample table with the date, currency, and exchange rate 
create table rates (
    id int identity(1,1) primary key, 
    date date not null, 
    currency char(3) not null, 
    rate decimal(10,2) not null 
) 
go 

-- create table of holidays we'll use for excluding rates records later 
create table holidays (
    id int identity(1, 1) primary key, 
    date date not null, 
    name varchar(100) not null 
) 

-- create some sample data 
-- Feb 18 and 19 are Saturday and Sunday 
insert into rates (date, currency, rate) values 
('2017-02-16', 'GBP', 1.23), 
('2017-02-17', 'GBP', 1.24), 
('2017-02-18', 'GBP', 1.25), 
('2017-02-19', 'GBP', 1.26), 
('2017-02-20', 'GBP', 1.27), 
('2017-02-16', 'SGD', 2.23), 
('2017-02-17', 'SGD', 2.24), 
('2017-02-18', 'SGD', 2.25), 
('2017-02-19', 'SGD', 2.26), 
('2017-02-20', 'SGD', 2.27); 

insert into holidays (date, name) values 
('2017-02-20', 'National Cherry Pie Day'); -- this is a real thing 


with t as (
    select id, 
      date, 
      currency, 
      rate, 
      row_number() over (partition by currency order by date desc) as age 
    from rates 
    where datepart(dw, date) not in (1, 7) -- sunday, saturday 
      and date not in (select date from holidays) -- exclude holiday rates 
) 
select * from t where age = 1; 
相關問題