【问题标题】:How to joining two tables with missing rows in the last month?如何在上个月加入两个缺失行的表?
【发布时间】:2019-04-11 22:05:33
【问题描述】:

我想加入两个表,其中一个表缺少每个货币组的一行。

表格:

按月汇总的本地货币交易。(交易表)

Date            Currency       spend
2019-01-01       EUR             100
2019-02-01       EUR             200 
2019-03-01       EUR             500
2019-04-01       EUR             214
2019-01-01       JYP            3200
2019-01-01       JYP            1534
2019-02-01       JYP            1534
2019-03-01       JYP            1534
2019-04-01       JYP            1534

按月汇率(exchange_data 表)

Month            Currency       Average Monthly rate
2019-01-01       EUR            1.2
2019-02-01       EUR            1.3 
2019-03-01       EUR            1.4
2019-01-01       JYP            101
2019-02-01       JYP            102
2019-03-01       JYP            103
2019-01-01       USA            1
2019-02-01       USA            1
2019-03-01       USA            1

我想执行联接以获取所有美元交易。问题是当月(2019-04-01)的汇率不可用。所以当月的所有交易在加入后都返回NULL。

我已经设法在 R 中解决了它,但是有没有办法用 SQL 来解决它? 我一直在尝试使用窗口函数但没有成功

LAG(rate,1) OVER (PARTITION BY currency ORDER BY month)

R 中的解决方案:假设速率保持不变。

library(lubridate)
library(dplyr)

exchange_previous <- exchange_data[exchange_data$month == floor_date(today(),"month") %m-% months(1),]
exchange_previous$month <- exchange_previous$month %m+% months(1)
exchange_data<-rbind(exchange_data,exchange_previous)

final <- transactions %>%
left_join(exchange_data, by = c("currency" = "name", "floor_date" = "month"))
Then simply multiply

【问题讨论】:

  • @GordonLinoff postgresql
  • 请为不使用 R 的 Postgres 用户发布所需的结果或 R 代码的输出。
  • 所有的 JPP 都意味着 JYP 吗?如果没有汇率,你会用上个月的吗?
  • @xavier 是的,我的错。 JPP是JYP。是的,上个月的那个

标签: sql r postgresql window-functions


【解决方案1】:

使用横向连接,但应该如下所示:

select t.*, ed.average_monthly_rate,
from transactions t left join lateral
     (select ed.*
      from exchange_data ed
      where ed.currency = t.currency and
            ed.month <= t.date
      order by ed.month desc
      fetch first 1 row only
     ) ed
     on 1=1;

我不确定你是要除以比率还是乘以比率。

【讨论】:

  • 玩的不错,横向连接我没想到ORDER BY month DESC LIMIT 1
【解决方案2】:

您可以使用LATERAL JOIN 应用货币的最新汇率,如下所示:

        SELECT tr.*, rates.rate
          FROM transactions tr
          LEFT JOIN
       LATERAL (SELECT rate
                     -- order rows by date, most recent first
                     , ROW_NUMBER() OVER (PARTITION BY currency 
                                              ORDER BY d DESC) rn 
                  FROM exchange_data 
                 WHERE currency = tr.currency 
                   -- exchange dates only up until the month of a transaction
                   AND d <= tr.d
             ) rates
            ON rates.rn = 1 -- row for the most recent date

LATERAL JOIN 类似于 SQL Server 中的APPLY,因为它允许您使用来自外部查询的谓词连接结果集。

Here's a working example on dbfiddle.

【讨论】:

  • 戈登使用ORDER BY month DESC LIMIT 1 的答案更好。
【解决方案3】:

假设您的表名为 Transactions 和 Exchange,以下代码适用于 MySQL。我猜 Postgresql 会是类似的。

select C.date, C.spend/E.Average 
   from Transactions as C, Exchange as E,
      (select A.date, A.Currency, Max(B.Month) as Month 
         from Transactions as A, Exchange as B
         where A.Currency = B.Currency and A.datum >= B.Month
         group by A.date, A.Currency
      ) as D
where C.date = D.date 
   and C.Currency = D.Currency 
   and E.Month = D.Month 
   and C.Currency = E.Currency
order by C.date;

其背后的想法如下:给定日期和货币,您查看表 D,这是该货币最接近的过去日期。一旦你有了它,你就可以得到你正在寻找的交换。

【讨论】:

    猜你喜欢
    • 2017-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多