2017-02-20 3 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; 
Смежные вопросы