Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
PHP. Практика создания Web-сайтов (второе издание). Авторы: Кузнецов М.В., Симдянов И.В. Программирование. Ступени успешной карьеры. Авторы: Кузнецов М.В., Симдянов И.В. C++. Мастер-класс в задачах и примерах. Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель MySQL 5. Авторы: Кузнецов М.В., Симдянов И.В. MySQL 5. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум MySQL

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Запрос к базе данных
 
 автор: kisit   (07.07.2010 в 00:22)   письмо автору
 
 

Есть таблица currency_course, в которой перечислены курсы валют за конкретную дату.
Поля таблицы currency_course:
currency (тип валюты — USD, EUR и т.д.),
date (дата установленного курса),
course (курс валюты)

Требуется выбрать последние курсы по каждой валюте.
запрос типа SELECT * FROM currency_course GROUP BY currency ORDER BY date_add DESC
работает неправильно

  Ответить  
 
 автор: Trianon   (07.07.2010 в 04:03)   письмо автору
 
   для: kisit   (07.07.2010 в 00:22)
 

чтобы эту решить, нужно сперва решить задачу попроще.
Выбрать последние даты курсов каждой валюты.

  Ответить  
 
 автор: kisit   (07.07.2010 в 22:47)   письмо автору
 
   для: Trianon   (07.07.2010 в 04:03)
 

это и так понятно, SELECT MAX(date) FROM currency_course GROUP BY currency. Не могу понять что как сделать дальше....

  Ответить  
 
 автор: sms-send   (07.07.2010 в 23:04)   письмо автору
 
   для: 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

  Ответить  
 
 автор: Лена   (07.07.2010 в 23:46)   письмо автору
 
   для: 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)

  Ответить  
 
 автор: sms-send   (07.07.2010 в 23:57)   письмо автору
 
   для: Лена   (07.07.2010 в 23:46)
 

Насколько я понял, автору нужно извлечь ещё третье поле со значением курса валюты за дату. А ваш внешний запрос во-первых будет работать только если дать имя подзапросу "(SELECT...) AS currency_course", во-вторых он не делает над результатами подзапроса ровно ничего (полезного). Выборка будет полностью эквивалентна этому запросу:

 SELECT currency, MAX(date) AS date FROM currency_course GROUP BY currency


т.е. просто тип валюты и дата последнего обновления, без значения курса.

  Ответить  
 
 автор: Лена   (08.07.2010 в 00:12)   письмо автору
 
   для: 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

  Ответить  
 
 автор: sms-send   (08.07.2010 в 00:38)   письмо автору
 
   для: Лена   (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).

  Ответить  
 
 автор: Trianon   (08.07.2010 в 03:04)   письмо автору
 
   для: Лена   (08.07.2010 в 00:12)
 

Что выбирает этот запрос?

SELECT course, currency, MAX( date ) AS date
FROM currency_course
GROUP BY currency 

  Ответить  
 
 автор: kisit   (08.07.2010 в 15:23)   письмо автору
 
   для: 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)

  Ответить  
 
 автор: Лена   (08.07.2010 в 20:25)   письмо автору
 
   для: Trianon   (08.07.2010 в 03:04)
 

Как я поняла, уникальные значения из поля currency(потому что по нему мы группируем),максимальную дату (результат агрегатной функции) и любое значение из поля course.

Интересно теперь, какой вариант из предложенных правильный.

  Ответить  
 
 автор: Trianon   (08.07.2010 в 20:32)   письмо автору
 
   для: Лена   (08.07.2010 в 20:25)
 

>Как я поняла, уникальные значения из поля currency(потому что по нему мы группируем),
верно

>максимальную дату (результат агрегатной функции)
максимальную для каждого из значений currency

>и любое значение из поля course.
а вот это - если повезет.
Потому что если не повезет, запрос просто отвергнут, как ошибочный.
Впрочем если бы приняли - какой прок в произвольном значении?

>Интересно теперь, какой вариант из предложенных правильный.

тот, что sms-send оставил в раннем посте

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования