Я думаю, вы этого хотите (добавьте индексы в свою таблицу, иначе это будет медленно):
SELECT curr.*,
prev.date AS `last date`, prev.price AS `last price`,
CONCAT(ROUND((curr.price/prev.price-1)*100,2),'%') AS `change`
FROM t curr
LEFT JOIN t prev
ON curr.priceTypeID=prev.priceTypeID
AND prev.date = (SELECT MAX(date)
FROM t findPrev
WHERE findPrev.priceTypeID=curr.priceTypeID
AND findPrev.date < curr.date)
ORDER BY date DESC, priceTypeID
Результат (первые строки):
Что он делает:
LEFT JOIN связывает таблицу с собой. Вам это понадобится, потому что вы хотите сравнить текущие (curr) значения из той же таблицы с предыдущими (предыдущими)
Подзапрос с третьим вхождением t, поскольку findPrev необходим, чтобы найти последнюю дату перед текущая дата (curr.date), которая будет максимальной датой ниже текущей.
Добавьте индексы к date
и priceTypeID
. И добавьте в свою таблицу первичный ключ. И на всякий случай, потому что это все испортит, если вы ошибетесь: убедитесь, что ваши даты находятся в типе данных DATE, а не в типе данных (VAR) CHAR.
Добавьте WHERE
if вы хотите сделать выбор, иначе вы получите всю таблицу, включая все даты.
Примечание : По возможности держитесь подальше от @variables в MySQL. С ними очень сложно получить надежные результаты. Иногда проходят месяцы, прежде чем вы заметите, что что-то идет не так.