Как связать две таблицы, но взять только значение MAX из одной таблицы в PostgreSQL? - PullRequest
0 голосов
/ 07 июня 2018

У меня есть две таблицы

exchange_rates
TIMESTAMP             curr1    curr2    rate
2018-04-01 00:00:00   EUR      GBP      0.89
2018-04-01 01:30:00   EUR      GBP      0.92
2018-04-01 01:20:00   USD      GBP      1.23

и

transactions
TIMESTAMP             user    curr    amount
2018-04-01 18:00:00   1       EUR     23.12
2018-04-01 14:00:00   1       USD     15.00
2018-04-01 01:00:00   2       EUR     55.00

Я хочу связать эти две таблицы на 1. валюте и 2. TIMESTAMP следующим образом:

  • curr в transactions должно быть равно curr1 в exchange_rates
  • TIMESTAMP в exchange_rates должно быть меньше или равно TIMESTAMP в transactions(поэтому мы подбираем только тот обменный курс, который был актуален на момент транзакции)

У меня есть это:

SELECT
trans.TIMESTAMP, trans.user,
-- Multiply the amount in transactions by the corresponding rate in exchange_rates
trans.amount * er.rate AS "Converted Amount"
FROM transactions trans, exchange_rates er
WHERE trans.curr = er.curr1
AND er.TIMESTAMP <= trans.TIMESTAMP
ORDER BY trans.user

, но это связано с двумя многими результатами, так каквыходных данных больше строк, чем в transactions.

желаемый результат:

TIMESTAMP             user    Converted Amount
2018-04-01 18:00:00   1       21.27
2018-04-01 14:00:00   1       18.45
2018-04-01 01:00:00   2       48.95

Логика Converted Amount:

  • строка 1:пользователь потратил в 18:00, поэтому возьмите rate, который меньше или равен TIMESTAMP в exchange_rates, то есть 0,92 для EUR в 01: 30
  • строка 2: пользователь потратил в 14:00поэтому возьмите rate, который меньше или равен TIMESTAMP в exchange_rates, то есть 1,23 для USD в 01: 20
  • строка 3: пользователь потратил в 01:00, поэтому возьмите rateэто меньше или равно TIMESTAMP в exchange_rates т.е. 0,89 для ЕСR в 00:00

Как я могу сделать это в postgresql 9,6 ?

1 Ответ

0 голосов
/ 07 июня 2018

Вы можете использовать LATERAL JOIN (CROSS APPLY) и ограничить результат первой строкой, соответствующей вашим условиям.

select t.dt, t.usr, t.amount * e.rate as conv_amount
from   transactions t
join lateral (select *
              from   exchange_rates er
              where  t.curr = er.curr1
              and    er.dt <= t.dt
              order by dt desc
              limit 1) e on true;
dt                  | usr | conv_amount
:------------------ | --: | ----------:
2018-04-01 18:00:00 |   1 |     21.2704
2018-04-01 14:00:00 |   1 |     18.4500
2018-04-01 01:00:00 |   2 |     48.9500

дБ <> скрипка здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...