Выборка данных из таблицы-журнала по дате

Для примера возьмем курсы валют. В таблице MySQL хранятся данные по курсам различных валют. Необходимо выбрать последние известные курсы для всех валют.

CREATE TABLE  `currency_rates` (
    `id` int(10) unsigned NOT NULL,
    `date` date NOT NULL,
    `id_currency` INT(10) unsigned  NOT NULL,
    `rates` int(10) unsigned NOT NULL)
ENGINE=MyISAM ;

INSERT INTO `currency_rates` (`id`, `date`, `id_currency`, `rates`) VALUES
(1, '2011-06-30', 1, 799),
(2, '2011-06-17', 2, 1151),
(3, '2011-07-02', 1, 802),
(4, '2011-07-01', 1, 801),
(5, '2011-06-18', 2, 1150),
(6, '2011-06-20', 2, 1120),
(7, '2011-06-17', 3, 27),
(8, '2011-07-04', 3, 29),
(9, '2011-06-13', 3, 25);

Казалось бы, нет ничего проще:

SELECT max( date ) , `rates` , `id_currency`
FROM `currency_rates`
GROUP BY `id_currency`
LIMIT 0 , 30

Но вот проанализировав результат этого запроса можно убедится в том, что кроме верной последней даты, результаты не верны:

max(date) rates id_currency
2011-07-02 799 1
2011-06-20 1151 2
2011-07-04 27 3

Запрос, возвращающий верный результат из MySQL выглядит так:

SELECT  t2.date, t2.id_currency, t2.rates
FROM (
  SELECT MAX(date) AS date, id_currency
  FROM currency_rates
  GROUP BY id_currency
) t1
JOIN currency_rates t2 ON t1.date = t2.date AND t1.id_currency = t2.id_currency

А вот и сам результат:

date rates id_currency
2011-07-02 802 1
2011-06-20 1120 2
2011-07-04 29 3

При наличии большого кол-ва данных запрос к MySQL с использованием группировки (GROUP BY) будет выполнятся весьма медленно. Во избежание "тормозов", необходимо хранить актуальные данные в отдельной таблице, например с названиями курсов валют:

CREATE TABLE `currency_names` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`currency_name` CHAR( 12 ) NOT NULL ,
`id_rates` INT UNSIGNED NOT NULL ,
`value_rates` INT UNSIGNED NOT NULL ,
`date_rates` DATE NOT NULL
) ENGINE = MYISAM ;

INSERT INTO `currency_names` (`id`, `currency_name`, `id_rates`, `value_rates`, `date_rates`) VALUES
(1, 'USD', 3, 802, '2011-07-02'),
(2, 'EUR', 6, 1120, '2011-06-20'),
(3, 'RUB', 3, 29, '2011-07-04');
Опубликовано: 2011/07/04
HTML-код ссылки на эту страницу:
<a href="https://petrenco.com/mysql.php?txt=68" target="_blank">Выборка данных из таблицы-журнала по дате MySQL</a>
9901
Комментарии
Спасибо, хорошая статья.
Суперский пост!
Согласен, что пост получился удачным. Хорошая работа!
Спасибо. Прочитал с интересом. Блог в избранное занес=)
Добавить комментарий
Ваш e-mail: (не виден посетителям сайта)
Ваше имя:
Комментарий:
Символы с картинки:
Только выделенные поля формы добавления комментариев обязательны к заполнению.