Это часть решения более сложной задачи .
Существует таблица с данными:
+------------+------+----------+-----------+
| date | data | data_max | data_diff |
+------------+------+----------+-----------+
| 2017-01-02 | 2 | 2 | NULL |
| 2017-01-03 | 4 | 4 | NULL |
| 2017-01-04 | 1 | 4 | -3 |
| 2017-01-05 | 3 | 4 | -1 |
| 2017-01-06 | 1 | 4 | -3 |
| 2017-01-07 | 4 | 4 | NULL |
| 2017-01-08 | 5 | 5 | NULL |
| 2017-01-09 | -2 | 5 | -7 |
| 2017-01-10 | 0 | 5 | -5 |
| 2017-01-11 | -5 | 5 | -10 |
| 2017-01-12 | 6 | 6 | NULL |
| 2017-01-13 | 4 | 6 | -2 |
+------------+------+----------+-----------+
Я хочу вычислить минимальное и максимальное значенияdata_diff
, но отдельно для каждого подмножества данных.Каждое подмножество данных начинается с NULL (но последний может заканчиваться не NULL, а данными). Мне также нужна дата начала и окончания каждого подмножества данных, которую я позже смогу использовать для вычисления значений Min, Max.Я хотел бы получить диапазоны дат:
+----------------+--------------+
| diff_date_from | diff_date_to |
+----------------+--------------+
| 2017-01-04 | 2017-01-06 |
| 2017-01-09 | 2017-01-11 |
| 2017-01-13 | 2017-01-13 |
+----------------+--------------+
Если вы хотите получить данные примера, вот запрос:
CREATE TABLE IF NOT EXISTS `test`
(
`date_time` DATETIME UNIQUE NOT NULL,
`data` INT NOT NULL
)
ENGINE InnoDB;
INSERT INTO `test` VALUES
('2017-01-02', 2),
('2017-01-03', 4),
('2017-01-04', 1),
('2017-01-05', 3),
('2017-01-06', 1),
('2017-01-07', 4),
('2017-01-08', 5),
('2017-01-09', -2),
('2017-01-10', 0),
('2017-01-11', -5),
('2017-01-12', 6),
('2017-01-13', 4)
;
SELECT
DATE(`date_time`) AS `date`,
`data`,
`data_max`,
IF(`data` < `data_max`, - (`data_max` - `data`), NULL)
AS `data_diff`
FROM
(
SELECT
`date_time`,
`data`,
MAX(`data`) OVER (ORDER BY `date_time` ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS `data_max`
FROM
`test`
) t
;
Можно ли написать один запрос, который обеспечитдиапазон дат как выше?Или должна быть применена процедура или какой-то трюк?
Возможно, оконная функция с OVER могла бы помочь, но я не знаю, как указать границу окна между текущей строкой, которая не является NULL, и началом предыдущих строк.из строки, которой предшествует NULL.Это вообще возможно?
Существует оператор RANGE
для установки границы окна Документация , которая выглядит многообещающе:
PRECEDING: Для ROWS граница - это строки expr перед текущей строкой, Для RANGE граница - это строки со значениями, равными текущему значению строки минус expr;если текущим значением строки является NULL, то пределом является пиров строки.
и другой части:
ORDER BY X ASC RANGEМЕЖДУ 10 ПРЕКРАСНЫМИ И 10 СЛЕДУЮЩИМИ
Кадр начинается с NULL и заканчивается на NULL, поэтому включает в себя только строки со значением NULL.
Но я не понимаю inlcuding only rows with null
.Возможно, для диапазона дат от 2017-01-02
до 2017-01-03
, но для 2017-01-03
до 2017-01-07
как получится?