使用联接在MySQL中转换货币

使用联接在MySQL中转换货币,mysql,Mysql,我有两张桌子: 不断更新的货币表(基于美元): +----+----------+-----------+ | id | currency | value_usd | +----+----------+-----------+ | 1 | USD | 1 | | 2 | AUD | 1.077315 | | 3 | GBP | 0.620868 | | 4 | EUR | 0.775338 | +----+--

我有两张桌子:

不断更新的
货币
表(基于美元):

 +----+----------+-----------+
 | id | currency | value_usd |
 +----+----------+-----------+
 |  1 | USD      | 1         |
 |  2 | AUD      | 1.077315  |
 |  3 | GBP      | 0.620868  |
 |  4 | EUR      | 0.775338  |
 +----+----------+-----------+
我有一个
订单
表,其中添加了新订单:

+----+-------------+----------+
| id | sales_total | currency |
+----+-------------+----------+
|  1 | 100         | USD      |
|  2 | 50          | GBP      |
|  3 | 75          | EUR      |
|  4 | 60          | GBP      |
+----+-------------+----------+
我有一个货币输入,它规定了我需要输出总额的货币类型,即使所有订单都存储在不同的货币中

例如,如果
$currency='EUR'根据
货币
表中的汇率查询
订单
表时,所有总计必须以欧元为单位。像这样:

+----+-------------+----------+-----------------+
| id | sales_total | currency | converted_total |
+----+-------------+----------+-----------------+
|  1 | 100         | USD      | 77.53           |
|  2 | 50          | GBP      | 62.44           |
|  3 | 75          | EUR      | 75.00           |
|  4 | 60          | GBP      | 74.92           |
+----+-------------+----------+-----------------+
我该怎么做?我想我需要某种
案例
陈述

应该这样做:

SELECT o.*, sales_total * (c2.value_usd / c1.value_usd) as converted_total,
       c2.currency as converted_currency
FROM `order` o
JOIN `currency` c1 ON o.currency = c1.currency
JOIN `currency` c2 ON c2.currency = 'EUR'
但是,如果没有样本DB,很难进行测试-计算可能已关闭,但原理很清楚。

这应该做到:

SELECT o.*, sales_total * (c2.value_usd / c1.value_usd) as converted_total,
       c2.currency as converted_currency
FROM `order` o
JOIN `currency` c1 ON o.currency = c1.currency
JOIN `currency` c2 ON c2.currency = 'EUR'

但是,如果没有示例DB,则很难进行测试-计算可能已关闭,但原理很清楚。

您可以通过子选择获得输出货币的系数,其余的则可以通过加入货币表进行测试:

SELECT 
  t2.id AS id, 
  t2.sales_total AS sales_total, 
  t2.currency AS currency,
  (t2.sales_total / value_usd * (SELECT value_usd FROM t1 WHERE currency = 'EUR')) AS converted_total
FROM t2 JOIN t1
  ON t1.currency = t2.currency

您可以通过子选择获得输出货币的系数,其余的可通过连接货币表获得:

SELECT 
  t2.id AS id, 
  t2.sales_total AS sales_total, 
  t2.currency AS currency,
  (t2.sales_total / value_usd * (SELECT value_usd FROM t1 WHERE currency = 'EUR')) AS converted_total
FROM t2 JOIN t1
  ON t1.currency = t2.currency

看来效果不错!只是一些变化。第一个联接应该是
o.currency=c1.currency
,第二个联接应该是
c2.currency='EUR'
。谢谢看来效果不错!只是一些变化。第一个联接应该是
o.currency=c1.currency
,第二个联接应该是
c2.currency='EUR'
。谢谢我还没有测试过这个,但假设它能工作,我相信它会比上面尼尔斯的慢。我很感激。一方面,我的解决方案有一个子选择,但这只需要评估一次,另一方面,Niels’还有一个连接。我刚刚测试了一些样本数据(90k记录)。我的速度稍微快了一点:~4.9秒对~5.4秒。在这种情况下,我得到了纠正。我看到的另一个区别是,如果'EUR'在
t1
中不存在,它将返回带有null的行。使用Niels的代码时,不会返回行。另一件事,如果
currency
表中的记录很少(少于160条),那么这些基准测试看起来还会一样吗?@JuanHoffmann有点让我惊讶,子查询速度更快,我预计两者都不会。您是否在
currency.currency
order.currency
上使用了索引,并重新运行了几次查询以消除缓存影响?有了适当的索引,即使是MySQL糟糕的查询优化器也应该能以极快的速度执行这两个查询,而不会有显著的差异。我还没有测试过这一个,但假设它能工作,我相信它会比上面Niels的速度慢。我很感激。一方面,我的解决方案有一个子选择,但这只需要评估一次,另一方面,Niels’还有一个连接。我刚刚测试了一些样本数据(90k记录)。我的速度稍微快了一点:~4.9秒对~5.4秒。在这种情况下,我得到了纠正。我看到的另一个区别是,如果'EUR'在
t1
中不存在,它将返回带有null的行。使用Niels的代码时,不会返回行。另一件事,如果
currency
表中的记录很少(少于160条),那么这些基准测试看起来还会一样吗?@JuanHoffmann有点让我惊讶,子查询速度更快,我预计两者都不会。您是否在
currency.currency
order.currency
上使用了索引,并重新运行了几次查询以消除缓存影响?有了适当的索引,即使是MySQL糟糕的查询优化器也应该以极快的速度执行这两个查询,而不会有显著的可测量的差异。货币转换仅在实际由货币交换执行时有效,例如在银行。剩下的时间你只是在向用户提供错误的信息。您应该使用您正在销售的商品的货币或用户在付款时将使用的货币进行交易。这是一个业务需求问题,而不是编程问题。这个需求有问题。货币转换仅在实际由货币交换执行时有效,例如在银行。剩下的时间你只是在向用户提供错误的信息。您应该使用您正在销售的商品的货币或用户在付款时将使用的货币进行交易。这是一个业务需求问题,而不是编程问题。