MYSQL Разница во времени между MAX и MIN из одной таблицы - PullRequest
2 голосов
/ 24 января 2012

У меня есть таблица, как описано ниже, и я пытаюсь получить значения MAX и MIN для определенного идентификатора, но только если дата ввода MAX больше, чем дата ввода MIN.

table:

ID  ENTRY_DATE              NAME       PRICE
1   2012-01-23 16:09:35     MONKEY     99.33
2   2012-01-23 11:04:09     MONKEY     97.65
3   2012-01-23 09:31:19     MONKEY     93.05
4   2012-01-23 15:12:14     DICE       30.49
5   2012-01-23 12:01:24     DICE       32.00
6   2012-01-23 08:01:24     DICE       31.00

Итак, я пытаюсь захватить MAX (цена) и MIN (цена), когда MAX (цена) entry_date больше, чем MIN (цена) entry_date.Исходя из таблицы выше, мой результат будет:

NAME      MaxPrice     MinPrice   PriceDiff   
MONKEY    99.33        93.05      6.28

«Кости» не будет отображаться, потому что МАКСИМАЛЬНАЯ дата / время происходит до МИН.Я не могу понять это.Вот то, что у меня есть сейчас, но, очевидно, он захватывает все результаты, так как я не могу понять, как сравнить даты входа ...

SELECT name,
MAX(price) as MaxPrice,
MIN(price) as MinPrice,
MAX(price)-MIN(price) AS PriceDiff,
FROM products
WHERE DATE(entry_date) = DATE(NOW()) 
GROUP BY name
ORDER BY PriceDiff DESC

Спасибо за помощь!

1 Ответ

2 голосов
/ 24 января 2012

Чтобы выбрать максимальную цену для группы (и соответствующую ей дату), вы должны:

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      |
+--------+---------------------+----------+---------------------+----------+-----------+
...