Я рассчитываю часы, что температура воздуха ниже 7,22. Я хочу сделать этот расчет на стороне SQL.
У меня есть следующая таблица
CREATE TABLE datas (
id INT,
air_temperature DOUBLE(8,2),
created_at TIMESTAMP
);
INSERT INTO datas (id, air_temperature, created_at) VALUES (1, 6.50, '2020-12-01 23:45:02');
INSERT INTO datas (id, air_temperature, created_at) VALUES (2, 6.50, '2020-12-02 03:45:02');
INSERT INTO datas (id, air_temperature, created_at) VALUES (3, 6.92, '2020-12-02 04:00:02');
INSERT INTO datas (id, air_temperature, created_at) VALUES (4, 6.99, '2020-12-02 04:15:02');
INSERT INTO datas (id, air_temperature, created_at) VALUES (5, 7.45, '2020-12-02 04:30:02');
INSERT INTO datas (id, air_temperature, created_at) VALUES (6, 7.34, '2020-12-02 04:45:02');
INSERT INTO datas (id, air_temperature, created_at) VALUES (7, 7.10, '2020-12-02 05:00:02');
INSERT INTO datas (id, air_temperature, created_at) VALUES (8, 7.00, '2020-12-02 05:20:02');
INSERT INTO datas (id, air_temperature, created_at) VALUES (9, 7.12, '2020-12-02 07:15:02');
Интервал данных может быть любым.
Что я хочу получить
date ch
2020-12-01 1
2020-12-02 3.083
2020-12-03 {calculatedValue}
2020-12-04 {calculatedValue}
Правила
если предыдущей строки нет, мы принимаем это за 1 час.
Если там есть; берем разницу двух дат. НО если выше чем 1 час, мы принимаем это как 1 час.
Как значение 2020-12-02 равно 3,083?
rowId 2 = take ch as 60 minutes (there's no previous row to compare, so take as 60 minutes. related to rule-1).
rowId 3 = take ch as 15 minutes. (the difference between the date of previous data and the date of current data)
rowId 4 = take ch as 15 minutes (same as rowId 3)
rowId 5 = take ch as 0 (it's not below 7.22)
rowId 6 = take ch as 0 (it's not below 7.22)
rowId 7 = take ch as 15 minutes (same as rowId 3)
rowId 8 = take ch as 20 minutes (same as rowId 3)
rowId 9 = take ch as 60 minutes (previous date is higher than 60 minutes. so take as 60 minutes. related to rule-2)
total minutes of day / 60 = 185 / 60 = 3.083 hours
Если я получу предыдущую дату значения, я могу сравнить и вычислить, но я не знаю, как я могу получить предыдущую строку при использовании группы.
Я думал что-то вроде этого, но я не уверен, как можно применить правила выше.
SELECT
DATE_FORMAT(created_at, '%d-%m-%Y') as `date`,
SUM((CASE WHEN air_temperature < 7.22 THEN (apply second rule here) ELSE 0 END)) as ch
FROM datas
GROUP BY `date`
Обновлено: dbfiddle
@Luuk уже 8, я могу использовать эти функции
Попробуйте и покажите, на что вы способны. (Тогда мы будем знать, где ваша настоящая проблема)
См. Почему я должен предоставлять MCRE для того, что мне кажется очень простым SQL-запросом
Неясно, когда ch 0.15
или ch 0.20
, также вы не предоставили подробностей о том, как вычисляется это значение 3.05
в вашем примере, и из примера неясно, откуда оно берется... Также структура таблицы (и имя таблицы! ) и некоторые примеры данных с желаемым результатом очень помогут в решении вашей проблемы. Но задача SO не в решении вашей проблемы, а в том, чтобы помочь ВАМ решить вашу собственную проблему.
@Клубничка, прости, я пропустил. Я добавил dbfiddle, этого достаточно?
@ Луук, ты прав. Я попытался уточнить это.
Вы можете использовать LEAD()
, чтобы получить следующий created_at
. Затем используйте арифметику, чтобы ограничить разницу до 60:
SELECT DATE_FORMAT(created_at, '%d-%m-%Y') as `date`,
SUM( COALESCE(LEAST(TIMESTAMPDIFF(minute, created_at, next_created_at), 60)), 60) / 60 as hours
FROM (SELECT d.*,
LEAD(created_at) OVER (ORDER BY created_at) as next_created_at
FROM datas d
) d
WHERE air_temperature < 7.22
GROUP BY `date`
Вы выводите 2.0833
, желаемый вывод 3.0833
. Кто может объяснить разницу?
Спасибо за ответ! Я добавил новые данные для 2020-12-01 23:45:02
. Теперь он правильно вычисляет 2020-12-02. но 2020-12-01 получает значение null, оно должно быть равно 1, потому что нет предыдущей строки для сравнения. так что берите как 60 минут (правило-1). как мы можем это сделать?
@аккобан . . . COALESCE()
должен поступить правильно в этом случае.
Какая у вас версия MySQL? потому что у 8.0 ЛИДЕР