我试图在这里摆脱我的分组最大查询中的子查询,这给了我不想要的using temporary
架构
CREATE TABLE IF NOT EXISTS `rates` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`currency_id` int(11) NOT NULL,
`rate` double NOT NULL,
`date` date NOT NULL,
`date_time` datetime NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `my` (`currency_id`,`date_time`),
KEY `currency` (`currency_id`),
KEY `date` (`date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
问题
我想要最新date_time
的the max(date) as date1
行和每个最新date_time
的行。date2 < date1
currency_id
简单来说:每种货币的今天最新汇率和前一天最新汇率。
这是我根据此处描述的每个组中的 Top-N技术提出的解决方案:http : //mysql.rjweb.org/doc.php/groupwise_max#top_n_in_each_group
SELECT
`id`, `currency_id`, `rate`, `date`, `date_time`, `n`
FROM
( SELECT @prev := '', @n := 0 ) init
JOIN
( SELECT @n := if(`currency_id` != @prev, 1, @n + 1) AS n,
@prev := `currency_id`,
`id`, `currency_id`, `rate`, `date`, `date_time`
FROM
( SELECT *
FROM
( SELECT *
FROM
`rates`
ORDER BY
`date_time` DESC ) v
GROUP BY
`currency_id`, `date` ) v
ORDER BY
`currency_id` ASC,
`date_time` DESC
) x
WHERE n <= 2;
摆弄测试数据:http ://sqlfiddle.com/#!9/54229/8
唉,FROM
状态中的子查询产生临时表......我想知道,甚至有可能避免高级分组最大问题上的临时表吗?
编辑
好的,我想我在这里得到了一些东西:http ://sqlfiddle.com/#!9/54229/55
SELECT
`id`, `currency_id`, `rate`, `date`, `date_time`
FROM
( SELECT @prev := '', @prev_date := '', @n := 0, @m := 0 ) init
JOIN
( SELECT @n := if(`prev` != @prev, 1, @n + if(`date` = @prev_date, 0, 1)) AS n,
@m := if(`date` != @prev_date, 1, @m + 1) AS m,
@prev := `prev`,
@prev_date := `date`,
`id`, `currency_id`, `rate`, `date`, `date_time`, `prev`
FROM (SELECT *, `currency_id` as `prev` FROM `rates`) v
ORDER BY
`prev` ASC,
`date_time` DESC
) x
WHERE n <= 2 AND m = 1;
编辑 2
最后,我的解决方案:http ://sqlfiddle.com/#!9/54229/59
SELECT
v.`id`, v.`currency_id`, v.`rate`, v2.`rate` as `rate_prev`, v.`rate` - v2.`rate` as `change`, v.`date`, v2.`date` as `date_prev`, v.`date_time`, v2.`date_time` as `date_time_prev`
FROM
( SELECT @group_by := '', @group_by_date := '', @n := 0, @m := 0 ) init
JOIN
( SELECT *,
@m := if(`date` != @group_by_date, 1, 0) AS `m`,
@n := if(`group_by` != @group_by, 1, @n + @m) AS `n`,
@group_by := `group_by`,
@group_by_date := `date`
FROM (SELECT *, `currency_id` as `group_by` FROM `rates` ORDER BY `currency_id`, `date` DESC, `date_time` DESC) v
) v ON v.n = 1 AND v.m = 1
LEFT JOIN
( SELECT *,
@m := if(`date` != @group_by_date, 1, 0) AS `m`,
@n := if(`group_by` != @group_by, 1, @n + @m) AS `n`,
@group_by := `group_by`,
@group_by_date := `date`
FROM (SELECT *, `currency_id` as `group_by` FROM `rates` ORDER BY `currency_id`, `date` DESC, `date_time` DESC) v
) v2 ON v.currency_id = v2.currency_id AND v2.n = 2 AND v2.m = 1
O(n)
性能和没有临时表。我还将结果加入到自身中以获取单行中的速率变化。