MySQL - 针对一系列列选择不同的值

标签 mysql distinct

下表将存储不同货币之间随时间变化的汇率:

CREATE TABLE `currency_exchange` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `currency_from` int(11) DEFAULT NULL,
 `currency_to` int(11) DEFAULT NULL,
 `rate_in` decimal(12,4) DEFAULT NULL,
 `rate_out` decimal(12,4) DEFAULT NULL,
 `exchange_date` datetime DEFAULT NULL,
 PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

我如何查询它以获取最新汇率列表?

本质上,它会将 currency_fromcurrency_to 列的组合识别为一种不同的汇率,然后查找具有最新日期的汇率。

例如,假设我得到的数据为:

INSERT INTO currency_exchange (id, currency_from, currency_to, rate_in, rate_out, exchange_date) VALUES
(1, 1, 2, 0.234, 1.789, '2012-07-23 09:24:34'),
(2, 2, 1, 0.234, 1.789, '2012-07-24 09:24:34'),
(3, 2, 1, 0.234, 1.789, '2012-07-24 09:24:35'),
(4, 1, 3, 0.234, 1.789, '2012-07-24 09:24:34');

我希望它选择行 ID:

  • 1 - 作为货币 1 和 2 之间的最新汇率
  • 3 - 作为货币 2 和 1 之间的最新汇率
  • 4 - 作为货币 1 和 3 之间的最新汇率

最佳答案

以下查询应该有效:

SELECT ce.*
FROM currency_exhcnage ce
LEFT JOIN currency_exchange newer
    ON (newer.currency_from = ce.currency_from
    AND newer.currency_to = ce.currency_to
    AND newer.exchange_date > ce.exchange_date)
WHERE newer.id IS NULL

进行自LEFT JOIN的技巧是避免使用子查询,如果您有大型数据集,子查询的成本可能会非常高。它本质上是在查找不存在“较新”记录的记录。

或者,您可以选择更简单的(尽管它可能(或可能不会,如评论中所述)更慢):

SELECT *
FROM currency_exchange ce
NATURAL JOIN (
    SELECT currency_from, currency_to, MAX(exchange_date) AS exchange_date
    FROM currency_exchange
    GROUP BY currency_from, currency_to
) AS most_recent

关于MySQL - 针对一系列列选择不同的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11614966/

相关文章:

mysql - 连接作为表的特定字段一部分的子字符串以创建新字段的正确代码

mysql - 在 debian 中更改 MariaDB 的 tmpdir

mysql - 如何在一个查询中两次使用表中的相同字段

mysql - 从 MySQL 表中获取顶级玩家

mysql - 用于显示唯一值的 SQL 语句

android - 如何将 sqlite3 关键字 DISTINCT 注入(inject)到 Android ContentProvider 的查询中?

php - HTML-PHP 登录后和登录前

MySQL从另一个表中获取最近的列

MySQL 为每个 Relational_ID 选择不同的列,其中最大时间戳低于 X

mysql - 基于其他列的 SUM(DISTINCT)