1

我有两张桌子

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. currency 和 2. TIMESTAMP:

  • currintransactions必须等于curr1inexchange_rates
  • TIMESTAMPinexchange_rates必须小于或等于TIMESTAMPin 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 消费,因此在 01:30 取rate小于或等于TIMESTAMPinexchange_rates即 0.92 的欧元
  • 第 2 行:用户在 14:00 消费,因此在 01:20 取rate小于或等于TIMESTAMPinexchange_rates即 1.23 美元的金额
  • 第 3 行:用户在 01:00 消费,因此在 00:00 取rate小于或等于TIMESTAMPinexchange_rates即 0.89 欧元的金额

如何在 postgresql 9.6 中执行此操作

4

1 回答 1

4

您可以使用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 | 用户名 | 转化金额
:----------------- | --: | ----------:
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

db<>在这里摆弄

于 2018-06-07T18:08:52.087 回答