|
|
|
| Есть таблица currency_course, в которой перечислены курсы валют за конкретную дату.
Поля таблицы currency_course:
currency (тип валюты — USD, EUR и т.д.),
date (дата установленного курса),
course (курс валюты)
Требуется выбрать последние курсы по каждой валюте.
запрос типа SELECT * FROM currency_course GROUP BY currency ORDER BY date_add DESC
работает неправильно | |
|
|
|
|
|
|
|
для: kisit
(07.07.2010 в 00:22)
| | чтобы эту решить, нужно сперва решить задачу попроще.
Выбрать последние даты курсов каждой валюты. | |
|
|
|
|
|
|
|
для: Trianon
(07.07.2010 в 04:03)
| | это и так понятно, SELECT MAX(date) FROM currency_course GROUP BY currency. Не могу понять что как сделать дальше.... | |
|
|
|
|
|
|
|
для: kisit
(07.07.2010 в 22:47)
| | Дальше пересечь с исходным набором.
SELECT currency_course.*
FROM
currency_course
INNER JOIN
(SELECT currency, MAX(date) AS date FROM currency_course GROUP BY currency) AS last_dates
ON currency_course.currency=last_dates.currency AND currency_course.date=last_dates.date
|
| |
|
|
|
|
|
|
|
для: sms-send
(07.07.2010 в 23:04)
| | Может я чего-то не понимаю, но зачем здесь INNER JOIN?
Почему нельзя просто выбрать из последних дат:
SELECT currency_course.* FROM( SELECT currency, MAX(date) AS date FROM currency_course GROUP BY currency) | |
|
|
|
|
|
|
|
для: Лена
(07.07.2010 в 23:46)
| | Насколько я понял, автору нужно извлечь ещё третье поле со значением курса валюты за дату. А ваш внешний запрос во-первых будет работать только если дать имя подзапросу "(SELECT...) AS currency_course", во-вторых он не делает над результатами подзапроса ровно ничего (полезного). Выборка будет полностью эквивалентна этому запросу:
SELECT currency, MAX(date) AS date FROM currency_course GROUP BY currency
|
т.е. просто тип валюты и дата последнего обновления, без значения курса. | |
|
|
|
|
|
|
|
для: sms-send
(07.07.2010 в 23:57)
| | Почему так нельзя?
SELECT ccc. *
FROM (
SELECT course, currency, MAX( date ) AS date
FROM currency_course
GROUP BY currency
) AS ccc
|
| |
|
|
|
|
|
|
|
для: Лена
(08.07.2010 в 00:12)
| | 1ый вариант:
SELECT ccc. *
FROM (
SELECT course, currency, MAX( date ) AS date
FROM currency_course
GROUP BY currency
) AS ccc
|
2ой вариант (просто подзапрос):
SELECT course, currency, MAX( date ) AS date
FROM currency_course
GROUP BY currency
|
В чём разница? Нет разницы. Лишняя конструкция.
Сам подзапрос составлен неверно. Если применяется группировка, то можно выбирать только группируемые поля и результаты агрегатных функций над группами значений остальных полей. У вас по полю currency группировки нет, значит и выбирать его нельзя.
Например, есть такой набор данных:
(картинка)
После группировки по полю currency, получаем 3 группы.
SELECT `currency`, GROUP_CONCAT( `date` ) AS `date` , GROUP_CONCAT( `course` ) AS `course`
FROM `currency_course`
GROUP BY `currency`
| (картинка)
С currency всё понятно, по этому столбцу мы группируем и значение будет атомарным для каждой группы. Но каждая группа содержит в себе по 2 даты и по 2 значения курса группируемой валюты (на картинке записаны через запятую). Конкретную дату из группы вы выбираете агрегатной функцией: MAX(date). А как выбрать конкретное значение группы из столбца course? Если указать просто наименование столбца, по которому группировка не производилась (course), то MySQL конечно ткнёт пальцем в небо и подставит какое то произвольное значение из списка, может даже угадает. А нам нужно чтобы это значение course было обязательно из той же строчки исходной таблицы, что и значение MAX(date). | |
|
|
|
|
|
|
|
для: Лена
(08.07.2010 в 00:12)
| | Что выбирает этот запрос?
SELECT course, currency, MAX( date ) AS date
FROM currency_course
GROUP BY currency
|
| |
|
|
|
|
|
|
|
для: Trianon
(08.07.2010 в 03:04)
| | решение задачи:
SELECT `actual`.`currency`,`currency_courses`.`course`
FROM
(
SELECT `currency`, MAX(`date`) `date`
FROM `currency_courses`
GROUP BY `currency`
) `actual`
LEFT JOIN `currency_courses` ON `currency_courses`.`currency`=`actual`.`currency` AND `currency_courses`.`date`=`actual`.`date`
еще вариант решения:
SELECT currency,course,date FROM currency_courses AS t1
WHERE t1.date = (SELECT MAX(date) FROM currency_courses AS t2 WHERE t1.currency = t2.currency) | |
|
|
|
|
|
|
|
для: Trianon
(08.07.2010 в 03:04)
| | Как я поняла, уникальные значения из поля currency(потому что по нему мы группируем),максимальную дату (результат агрегатной функции) и любое значение из поля course.
Интересно теперь, какой вариант из предложенных правильный. | |
|
|
|
|
|
|
|
для: Лена
(08.07.2010 в 20:25)
| | >Как я поняла, уникальные значения из поля currency(потому что по нему мы группируем),
верно
>максимальную дату (результат агрегатной функции)
максимальную для каждого из значений currency
>и любое значение из поля course.
а вот это - если повезет.
Потому что если не повезет, запрос просто отвергнут, как ошибочный.
Впрочем если бы приняли - какой прок в произвольном значении?
>Интересно теперь, какой вариант из предложенных правильный.
тот, что sms-send оставил в раннем посте | |
|
|
|