MySQL для выбора диапазона дат, где сумма меньше значения - PullRequest
3 голосов
/ 10 апреля 2020

У меня есть MySQL база данных с информацией о погоде:

Date       | Rain
2001-01-01 | 0.0
2001-01-02 | 0.2
2001-01-03 | 0.0

Эта таблица содержит данные почти за 20 лет. Одна запись в день.

Я хочу получить все периоды засухи из базы данных. Определение: менее 0,5 мм дождя за период не менее 20 дней.

Я мог бы сделать oop в PHP и повторить все данные и подсчитать сумму за последние 20 дней. Но мне было интересно, можно ли это сделать в выражении MySQL.

Чтобы сделать его еще более сложным, я также хочу, чтобы продолжительность периода засухи была в днях.

Итак, если период засухи начинается с 2020-04-01 и заканчивается 2020-04-25, то я хочу получить сумму дождя (которая всегда меньше 0,5 мм) и продолжительность 25 дней. , Теоретически в этом случае существует период засухи с 2020-04-02 по 2020-04-21, но это внутри другого периода. Поэтому мне нужен только самый длинный период.

Каков наилучший способ добиться этого в MySQL?

MySQL версия: 5.5.31

Запросить создать таблицу с данными:

CREATE TABLE `dayRecords` (
  `Date` date NOT NULL,
  `Rain` decimal(10,1) DEFAULT NULL
) ENGINE=MyISAM;

INSERT INTO `dayRecords` (`Date`, `Rain`) VALUES
('2020-03-10', '11.0'),
('2020-03-11', '10.8'),
('2020-03-12', '2.2'),
('2020-03-13', '1.8'),
('2020-03-14', '0.0'),
('2020-03-15', '0.0'),
('2020-03-16', '0.0'),
('2020-03-17', '0.0'),
('2020-03-18', '0.0'),
('2020-03-19', '0.0'),
('2020-03-20', '0.0'),
('2020-03-21', '0.2'),
('2020-03-22', '0.0'),
('2020-03-23', '0.0'),
('2020-03-24', '0.0'),
('2020-03-25', '0.0'),
('2020-03-26', '0.0'),
('2020-03-27', '0.0'),
('2020-03-28', '0.0'),
('2020-03-29', '0.0'),
('2020-03-30', '0.0'),
('2020-03-31', '0.0'),
('2020-04-01', '0.2'),
('2020-04-02', '0.0'),
('2020-04-03', '0.0'),
('2020-04-04', '0.0'),
('2020-04-05', '0.0'),
('2020-04-06', '0.0'),
('2020-04-07', '0.0'),
('2020-04-08', '0.0'),
('2020-04-09', '0.2');

ALTER TABLE `dayRecords`
  ADD PRIMARY KEY (`Date`);

Желаемый результат:

start      | end        | total | duration
2020-03-14 | 2020-04-08 | 0.4   | 26

1 Ответ

1 голос
/ 10 апреля 2020

Мой конечный результат немного отличается от вашего. Потому что у меня есть 09.04, но у меня также есть результат 26 дней подряд.

SELECT 
    MIN(`Date`) start,
    MAX(`Date`) end,
    ROUND(MAX(total_rain),1) total,
    SUM(isdRoud=1) duration
FROM
    (SELECT 
        `Date`,

            IF( `Rain` > 0.5, IF(@droud = 3,@droud := 3,@droud := 2), @droud := 1) isdRoud,
            IF (`Rain` > 0.5 AND @droud  = 2, @cat:= @cat + 1, @cat:= @cat) categorie,
            IF(@droud = 2,@droud := 3,@droud := @droud) nextrain,
            IF (@droud  = 3 OR @droud  = 2, @rain:= 0, @rain:= @rain) resetrain,
            IF(@droud = 1,@rain:=@rain + `Rain`,@rain:=@rain) total_rain
    FROM
        (SELECT 
        *
    FROM
        `dayRecords`
    ORDER BY `Date` DESC) t1
     , (SELECT @rain:=0.0) t2 
     , (SELECT @droud:=1) t3
     , (SELECT @cat:=0) t4) t5
WHERE
    isdroud = 1
GROUP BY categorie
HAVING duration >= 20;
start      | end        | total | duration
:--------- | :--------- | ----: | -------:
2020-03-21 | 2020-04-09 |   0.4 |       20
2019-04-04 | 2019-04-23 |   0.2 |       20

db <> скрипка здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...