Расчет обмена валюты в SAS

У меня есть две таблицы, первая учетная запись состоит из следующих данных:

Code | Exposure | Expo_Curr | Limit | Limit_curr | Date_extr  

2105 | 2.354586 | EUR | 288.6 | HUF | 1405  
2105 | 25.46658 | USD | 12.32 | CAD | 1203  
2105 | 5.987456 | CAD | 321.2 | CZK | 1107  
2105 | 9.658785 | HRK | 5.365 | EUR | 1103  

Вторая таблица состоит из обменного курса

Code | date_extr | currency_from | currency_to | fx_rate  

2105 | 1405 | HUF | EUR | 4.36  
2105 | 1203 | USD | EUR | 3.62  
2105 | 1203 | CAD | EUR | 1.23  
2105 | 1107 | CAD | EUR | 1.17  
2105 | 1107 | CZK | EUR | 24.6  
2105 | 1103 | HRK | EUR | 35.6  

Мне нужно создать таблицу, в которой Exposure и Limit будут переведены в евро в соответствии с обменным курсом во второй таблице. Если данные уже указаны в евро, их нужно просто умножить на 1, а остальные рассчитать по ставке во второй таблице. Ставка также должна соответствовать date_extr (ГГММ, если ставка действительна).

Должно выглядеть так:

Code | Exposure | Expo_Curr | Limit | Limit_curr | Date_extr  

2105 | 2.354586*1.00 | EUR | 288.6*4.36 | HUF | 1405  
2105 | 25.46658*3.62 | USD | 12.32*1.23 | CAD | 1203  
2105 | 5.987456*1.17 | CAD | 321.2*24.6 | CZK | 1107  
2105 | 9.658785*35.6 | HRK | 5.365*1.00 | EUR | 1103  

Я работаю над SAS, поэтому я попытался сделать это с помощью соединения SQL, но не смог заставить его работать. Если кто-нибудь может помочь разобраться, как я могу это сделать? У меня есть больше столбцов для таких расчетов.

Заранее спасибо.


person Noza    schedule 05.08.2016    source источник


Ответы (2)


Вы можете использовать подход с использованием хеш-таблицы и расширить хеш-ключи и соответствующие поисковые запросы на столько переменных соответствия, сколько вам нужно:

data want ;
  if _n_ = 1 then do ;
    /* Define & load hash table of conversions */
    length currency_from $3. date_extr fx_rate 8. ;
    declare hash exc (dataset:"exchange") ;
    exc.defineKey('currency_from','date_extr') ; /* extend this to more variables */
    exc.defineData('fx_rate') ;
    exc.defineDone() ;
    call missing(of currency_from--fx_rate) ;
  end ;

  set accounts ;

  /* Lookup Expo_Curr + date_extr in hash table */
  rc = exc.find(key:expo_curr,key:date_extr) ; /* extend this to match */
  if rc = 0 then do ;
    expo_rate = fx_rate ;
    exposure2 = exposure * expo_rate ;
  end ;

  /* Lookup Limit_Curr + date_extr in hash table */
  rc = exc.find(key:limit_curr,key:date_extr) ; /* extend this to match */
  if rc = 0 then do ;
    limit_rate = fx_rate ;
    limit2 = limit * limit_rate ;
  end ;

  drop rc ;
run ;

https://support.sas.com/documentation/cdl/en/lrdict/64316/HTML/default/viewer.htm#a003143739.htm.

person Chris J    schedule 05.08.2016
comment
большое спасибо! Работает :) Попробую сейчас узнать больше о хешировании. - person Noza; 05.08.2016

Вам просто нужно дважды выйти за стол FX. Один для ограничения, один для воздействия.

E.g.

SELECT
  CASE
    WHEN acc.expo_curr = 'EUR'
    THEN acc.exposure
    ELSE acc.exposure * expo.fx_rate
  END AS exposure,
  acc.expo_curr,
  CASE
    WHEN acc.limit_curr = 'EUR'
    THEN acc.limit
    ELSE acc.limit * lim.fx_rate
  END AS limit,
  acc.limit_curr
FROM account acc
LEFT JOIN exchange expo
  ON  expo.date_extr = acc.date_extr
  AND expo.currency_from = acc.expo_curr
  AND expo.currency_to = 'EUR'
LEFT JOIN exchange lim
  ON  lim.date_extr = acc.date_extr
  AND lim.currency_from = acc.limit_curr
  AND lim.currency_to = 'EUR'
person Andy N    schedule 05.08.2016
comment
Спасибо, Энди, есть ли другой вариант, потому что на самом деле мне нужно вычислить 5 таких столбцов из 1 таблицы, а создание 5 объединений займет много времени, потому что таблица Account довольно большая. Заранее спасибо! - person Noza; 05.08.2016
comment
Загляните в хеш-таблицы, кажется, идеальный кандидат для этого типа проблемы. - person Chris J; 05.08.2016
comment
@Noza не беспокойтесь о размере таблицы Account. Используя этот запрос, вы проведете только одно сканирование таблицы. Проблема (в данном случае) возникнет, если ваши FX-столы будут очень большими. - person Andy N; 05.08.2016
comment
..если бы 5 сумм в таблице Account были сохранены в 5 строках, а не в 5 столбцах, решение могло бы быть лучше. - person Andy N; 05.08.2016
comment
@AndyN, спасибо, я не могу изменить структуру учетной записи в таблице, но я попробую запустить ее с образцом, который вы мне дали. большое спасибо. - person Noza; 05.08.2016
comment
@ChrisJ, можешь показать мне небольшой образец? Я никогда не использовал хеши. может быть другое решение? - person Noza; 05.08.2016