MySQL вычисляет процент по строкам по датам в диапазоне

#mysql #calculation

Вопрос:

Я использую MySQL 5.6, и у меня есть таблица, содержащая множество записей, подобных этой…

  ---- ------------ ------- 
| id | date       | price |
 ---- ------------ ------- 
|  1 | 2000-01-01 |  1.56 |
|  1 | 2000-01-05 |  1.90 |
|  1 | 2000-02-02 |  1.44 |
|  2 | 2000-01-01 | 10.99 |
|  2 | 2000-01-07 |  9.88 |
|  2 | 2000-02-01 |  9.64 |
 ---- ------------ ------- 
 

Для каждого идентификатора я хотел бы вернуть следующее…

  1. ID
  2. Минимальная дата >= 1 месяц назад
  3. Максимальная дата
  4. Процентная разница в цене, основанная на ценах на 2 возвращенные даты
  5. возможно, даже покажут цену на эти даты

например, если данные таблицы были (на сегодняшний день 2000-02-01)…

  ---- ------------ ------- 
| id | date       | price |
 ---- ------------ ------- 
|  1 | 2000-01-01 |  1.00 |
|  1 | 2000-02-01 |  1.10 |
|  2 | 2000-01-04 |  1.00 |
|  2 | 2000-02-01 |  2.00 |
 ---- ------------ ------- 
 

Тогда я ожидал бы увидеть…

  ---- ------------ ------------ ------------ 
| id | min        | max        | percentage |
 ---- ------------ ------------ ------------ 
|  1 | 2000-01-01 | 2000-02-01 |        10% |
|  2 | 2000-01-04 | 2000-02-01 |       100% |
 ---- ------------ ------------ ------------ 
 

Поэтому мои вопросы таковы: как мне это сделать? и, что более важно, каковы логические шаги в этом направлении?

Комментарии:

1. Пожалуйста, отформатируйте эти примеры данных в виде кода, чтобы они были более удобочитаемыми

2. Кроме того, пожалуйста, добавьте свой SQL, который вы пытались использовать.

3. @Patriot, все это выглядело хорошо, когда я просматривал его перед отправкой, но после отправки оно выглядело ужасно. Теперь я изменил его.

4. @Wannabe-Кодер ТАКИМ образом удаляет разрывы строк, если вы не заключите текст в блок кода.

5. @Raki, извините, что я выбросил все это в отчаянии 🙁 Лучшее, что мне удалось, — это получить минимальную/максимальную дату, но я не смог продвинуться дальше.

Ответ №1:

Вы могли бы начать с этого, это оставляет много возможностей для улучшения:

 DROP TABLE IF EXISTS price;
CREATE TABLE price (id int ,`date` date,price decimal(8,2));
INSERT INTO price VALUES
('1','2000-01-01','1.56'),
('1','2000-01-05','1.90'),
('1','2000-02-02','1.44'),
('2','2000-01-01','10.99'),
('2','2000-01-07','9.88'),
('2','2000-02-01','9.64');


select id,`min`,`max`,`price1`,`price2`,
    round((price2-price1)/price1*100,2) as `percentage`
from (
   select id,`min`,`max`,
       (select price from price p1 where p1.id=x.id and p1.`date`=x.`min`) as price1,
       (select price from price p1 where p1.id=x.id and p1.`date`=x.`max`) as price2
   from (
      select 
         id,
         min(`date`) as `min`,
         max(`date`) as `max`
      from price
      where `date` between '2000-01-01' and '2000-02-01'
      -- where `date` between date_add(current_date(), INTERVAL -1 month) and current_date()
      group by id) x
   ) x2;
 

ПРИМЕЧАНИЕ: WHERE Предложение с комментариями предназначено для фильтрации последнего месяца перед текущей датой. Предложение used WHERE предназначено только для того, чтобы заставить его работать с образцами данных.

ПРИМЕЧАНИЕ 2: Я назвал таблицу price , потому что в вопросе не было указано имя. Если вам действительно нужно было решение, которое лучше соответствовало бы вашей текущей ситуации, вы должны были предоставить create table... (DDL) для используемой вами таблицы вместе с некоторыми образцами данных.

ПРИМЕЧАНИЕ 3: Вы не должны использовать зарезервированные слова в качестве имен столбцов, например date , min и max в этом коде…

Комментарии:

1. спасибо за ваш ответ, это именно то, что мне было нужно. Сейчас я уйду и проанализирую ваш ответ, чтобы понять, как он работает. Я также приму во внимание все комментарии и постараюсь задавать лучшие вопросы в будущем 🙁 Я также постараюсь узнать больше о SQL, но TBH, как и многое другое в кодировании, изучение чего-либо-это не 5-минутная задача, и форумы, подобные этому, обычно намного быстрее получают ответ.

2. еще раз для моего назидания, когда вы говорите «возможности для улучшения», вы говорите о производительности или о чем-то другом?

3. «Пространство для улучшения» необходимо, когда у вас больше данных, чем 6 записей, и нет индексов.

4. Хотя я согласен с тем, что рекомендуется избегать использования ключевых слов в качестве идентификаторов таблиц/столбцов, ни одно из упомянутых слов не зарезервировано