Условие для GROUP BY

Статус
В этой теме нельзя размещать новые ответы.

venetu

Мой дом здесь!
Регистрация
28 Мар 2007
Сообщения
745
Реакции
273
Есть таблица
id, products_id, price, date

В которой записаны цены на продукты. У каждого продукта - несколько цен, в зависимости от даты. Актуальна всегда последняя цена (с самым большим date), прошлые хранятся для истории. Цены меняются далеко не ежедневно, т.е. не для каждой даты есть соотв. запись в таблице.

Задача: селектнуть самые новые цены.

причем так, чтоб потом в этот запрос еще можно было вставить WHERE `date` < '2009-01-01', т.е. "последние(актуальные) цены по состоянию на такое-то число"


Я подозреваю, что тут надо копать в сторону HAVING, но
SELECT products_id, price, date FROM table GROUP BY products_id HAVING date=MAX(date) нужного результата не дает. Наверное, MAX() считается по всей таблице, а не для каждого products_id отдельно.

Короче в более общем случае можно сформулировать так - как сказать мускулу, чтоб при GROUP BY он из группы оставил конкретный какой-то ряд (в моем случае - запись с максимальным date).
 
один из вариантов с субзапросами, один запрос делает список продуктов и их максимальной даты, а другой запрос составляет весь список по первому сверяя по дате и ид продукта
Код:
SELECT t1.* FROM product t1, 
(
    SELECT products_id, MAX(date) date
    FROM product
    ##или с условием
    ##WHERE date < '2010-04-14'
    GROUP BY products_id 
    ORDER BY date
) filter

WHERE t1.products_id=filter.products_id AND t1.date=filter.date
;
 
Можно так еще:
SELECT
t.date,
t.products_id,
t.price
FROM test t
WHERE t.date=(SELECT max(t1.date) FROM test t1 WHERE t1.products_id = t.products_id /*здесь можно вставить условие на дату*/)

По-моему, с Group by не получится сделать задуманное.
 
Это старая больная проблема MySQL, у неё даже есть название (не вспомню сейчас), было много обсуждений на mysql.com. Над ней смеются все крутые спецы по БД (Oracle, MS-SQL, Postgre)

На самом деле в нормальных SQL нельзя вытащить из запроса с GROUP BY значения полученые не из групповых ф-ций (MAX, MIN, AVG, GROUP_CONCAT и т.д.) либо полей не участвующих в перечислении GROUP BY

Можно так еще:
SELECT
t.date,
t.products_id,
t.price
FROM test t
WHERE t.date=(SELECT max(t1.date) FROM test t1 WHERE t1.products_id = t.products_id )
По-моему, с Group by не получится сделать задуманное.
В одну дату может выйти 2 значения

Я раньше использовал вариант polyetilen, только ORDER BY date DESC

Теоретически mysql не гарантирует что в этом запросе будет возвращено первое значение, но на деле оно работает :)

Но потом я вообще отказался от таких запросов в пользу реструктуризации БД и создания спец. выборок последних продуктов.
 
Судя по информации от ТС ("Актуальна всегда последняя цена (с самым большим date)"), то не может.
Да, верно, если там тип datetime, я что-то подумал, что date :)

WHERE t.date=(SELECT max(t1.date) FROM test t1 WHERE t1.products_id = t.products_id )
А вот такая конструкция может оказаться ооочень медленной, если будет извлекаться много строк. По одному доп. запросу на каждую строку.

Я обычно стараюсь использовать простые запросы в подобных случаях (да и ОРМ навязывает ;)). 1м вытаскиваю IDшки, 2м достаю уже данные.
 
Статус
В этой теме нельзя размещать новые ответы.
Назад
Сверху