#mysql #sql #gaps-and-islands #mariadb-10.2
#mysql #sql #пробелы и острова #mariadb-10.2
Вопрос:
У меня есть таблица events
следующего вида:
f_id leg
1 1
2 1
3 1
4 2
5 2
6 3
7 1
8 1
9 2
Мне нужен текущий итог каждого leg
изменения. Ожидаемый результат:
f_id leg total_legs
1 1 1
2 1 1
3 1 1
4 2 2
5 2 2
6 3 3
7 1 4
8 1 4
9 2 5
Не уверен, как это сделать.
SELECT *, @leg_var:=IF(@current_leg=leg, leg) as total_legs FROM `events`
Это явно неправильно.
Комментарии:
1. Какую версию MySQL вы используете?
2. Использование MariaDB 10.2
Ответ №1:
WITH cte AS ( SELECT *, CASE WHEN LAG(leg) OVER (ORDER BY f_id) = leg
THEN 0
ELSE 1
END lag_leg
FROM test )
SELECT f_id, leg, SUM(lag_leg) OVER (ORDER BY f_id) total_legs
FROM cte;
Ответ №2:
Это своего рода проблема пробелов и островов. В MySQL 8.0 вы можете использовать lag()
и накопительный sum()
:
select fid, leg, sum(not leg <=> lag_leg) over(order by f_id) total_legs
from (
select e.*, lag(leg) over(order by f_id) lag_leg
from events e
) e
Ответ №3:
Проблема может быть решена без оконных функций с использованием переменных:
SET @leg_var:=null;
SET @total:=0;
SELECT
f_id,
@leg_var prev_leg,
@total:=@total if(@leg_var is null or @leg_var<>leg, 1, 0) as total,
@leg_var:=leg as leg
FROM events
ORDER BY f_id;