Чтобы выбрать максимальную цену для группы (и соответствующую ей дату), вы должны:
SELECT p.NAME, p.ENTRY_DATE as dateofMax, p.PRICE as maxPrice
FROM products p
LEFT JOIN products p2
ON p.NAME=p2.NAME AND p.PRICE<p2.PRICE
WHERE p2.PRICE IS NULL;
То, что это делает, присоединяется products
к себе на name
, образуя каждую возможную пару цен в каждом имени, где p.PRICE<p2.PRICE
. Поскольку это левое соединение, если в p
есть цена, для которой в p2
нет большей цены, для p2.PRICE
будет установлено значение NULL.
Таким образом, этот запрос выбирает строку, в которой нет более высокой цены, то есть строка из максимальной цены (за группу, равную NAME
).
Чтобы выбрать минимальную цену для группы (и соответствующую дату), вы меняете <
на >
в LEFT JOIN
, и поэтому мы выбираем строку, для которой мы не можем найти меньше цена в таблице для этого имени.
Поскольку вы хотите выбрать оба макс. и мин., Эти две таблицы необходимо объединить.
Решение
Это означает 3 самостоятельных соединения product
к себе, где две таблицы product
используются для расчета максимальной цены / даты, а две другие используются для вычисления минимума.
В приведенном ниже запросе все строки, кроме последней, создадут таблицу с максимальной ценой и ее датой, а также минимальной ценой и ее датой. Последнее навязывает условие «цена максимума происходит после цены минимума».
Таблицы p,p2
используются для расчета максимальной цены, а p3,p4
- для расчета минимальной цены. Это все равно будет работать, если p3
будет объединено только с p
ON p.NAME=p3.NAME
, но дополнительное условие p3.price<=p.price
удаляет ненужные нам строки (нет смысла искать минимальную цену для строк, для которых цена больше максимума!).
-- select max price & date of max & min price & date of min:
SELECT p.NAME, p.ENTRY_DATE as dateofMax, p.PRICE as maxPrice,
p3.ENTRY_DATE as dateofMin, p3.PRICE as minPrice,
p.PRICE-p3.PRICE as PriceDiff
FROM products p
LEFT JOIN products p2
ON p.NAME=p2.NAME AND p.PRICE<p2.PRICE
LEFT JOIN products p3
ON p.NAME=p3.NAME AND p3.price<=p.price
LEFT JOIN products p4
ON p.NAME=p4.NAME AND p3.price>p4.price
WHERE p2.PRICE IS NULL
AND p4.PRICE IS NULL
AND p.ENTRY_DATE>p3.ENTRY_DATE; -- make sure dateOfMax>dateofMin
, что дает
+--------+---------------------+----------+---------------------+----------+-----------+
| NAME | dateofMax | maxPrice | dateofMin | minPrice | PriceDiff |
+--------+---------------------+----------+---------------------+----------+-----------+
| MONKEY | 2012-01-23 16:09:35 | 99.33 | 2012-01-23 09:31:19 | 93.05 | 6.28 |
+--------+---------------------+----------+---------------------+----------+-----------+