Разбор пятничной задачки.
Данные задачки решаются с помощью оконок и флагов (меток) 🤓❗️
Главное не запутаться.
Предлагаю свое решение:
WITH t1 AS ( -- проставляем флаги
SELECT t.*,
CASE WHEN end_t = LEAD(start_t) OVER (PARTITION BY phone_number ORDER BY start_t) THEN 1 ELSE 0 END AS start_lead, -- если end_t равен start_t след строки , ставим флаг 1
CASE WHEN start_t = LAG(end_t) OVER (PARTITION BY phone_number ORDER BY start_t) THEN 1 ELSE 0 END AS end_lag -- если start_t равен end_t пред строки, ставим флаг 1
FROM test_table t
)
SELECT DISTINCT phone_number,
CASE WHEN end_lag = 1 THEN LAG(start_t) OVER (PARTITION BY phone_number ORDER BY start_t) ELSE start_t END AS start_t,
CASE WHEN start_lead = 1 THEN LEAD(end_t) OVER (PARTITION BY phone_number ORDER BY start_t) ELSE end_t END AS end_t
FROM t1
-- строки с двумя флагами 1 надо отрезать
WHERE start_lead = 0
OR end_lag = 0
ORDER BY phone_number;
▪️Сначала проставляем флаги по нашей придуманной логике.
▪️Отрезаем лишние строки при помощи флагов.
▪️В последнем шаге правильно проставляем start_t и end_t.
В комментариях было выложено очень крутое 'https://t.me/data_penguin/48?comment=215' rel='nofollow'>правильное решение. Здесь классно используется накопительная сумма (оконка sum) и group by с min и max 👍
with t1 as (
select phone_number, start_t, end_t,
case when start_t = lag(end_t) over (partition by phone_number order by start_t) then 0 else 1 end as metka
from test_table),
t2 as (
select phone_number, start_t, end_t,
sum(metka) over (partition by phone_number order by start_t) as shlop
from t1)
select phone_number, min(start_t) as start_t, max(end_t) as end_t
from t2
group by 1, shlop
order by 1, 2
Решений таких задач можно много придумать. Полный разбор текстом не вижу смысла делать😄💅
Все скрипты создания таблицы и наполнения данными есть. Решения тоже есть. Кому интересно, посидите покрутите, будет точно полезно👍 На собеседование на мидла подобную задачу могут дать 💯
Если у кого еще появятся идеи, обязательно делитесь. Будем обсуждать😊
#sql #задача
Данные задачки решаются с помощью оконок и флагов (меток) 🤓❗️
Главное не запутаться.
Предлагаю свое решение:
WITH t1 AS ( -- проставляем флаги
SELECT t.*,
CASE WHEN end_t = LEAD(start_t) OVER (PARTITION BY phone_number ORDER BY start_t) THEN 1 ELSE 0 END AS start_lead, -- если end_t равен start_t след строки , ставим флаг 1
CASE WHEN start_t = LAG(end_t) OVER (PARTITION BY phone_number ORDER BY start_t) THEN 1 ELSE 0 END AS end_lag -- если start_t равен end_t пред строки, ставим флаг 1
FROM test_table t
)
SELECT DISTINCT phone_number,
CASE WHEN end_lag = 1 THEN LAG(start_t) OVER (PARTITION BY phone_number ORDER BY start_t) ELSE start_t END AS start_t,
CASE WHEN start_lead = 1 THEN LEAD(end_t) OVER (PARTITION BY phone_number ORDER BY start_t) ELSE end_t END AS end_t
FROM t1
-- строки с двумя флагами 1 надо отрезать
WHERE start_lead = 0
OR end_lag = 0
ORDER BY phone_number;
▪️Сначала проставляем флаги по нашей придуманной логике.
▪️Отрезаем лишние строки при помощи флагов.
▪️В последнем шаге правильно проставляем start_t и end_t.
В комментариях было выложено очень крутое 'https://t.me/data_penguin/48?comment=215' rel='nofollow'>правильное решение. Здесь классно используется накопительная сумма (оконка sum) и group by с min и max 👍
with t1 as (
select phone_number, start_t, end_t,
case when start_t = lag(end_t) over (partition by phone_number order by start_t) then 0 else 1 end as metka
from test_table),
t2 as (
select phone_number, start_t, end_t,
sum(metka) over (partition by phone_number order by start_t) as shlop
from t1)
select phone_number, min(start_t) as start_t, max(end_t) as end_t
from t2
group by 1, shlop
order by 1, 2
Решений таких задач можно много придумать. Полный разбор текстом не вижу смысла делать😄💅
Все скрипты создания таблицы и наполнения данными есть. Решения тоже есть. Кому интересно, посидите покрутите, будет точно полезно👍 На собеседование на мидла подобную задачу могут дать 💯
Если у кого еще появятся идеи, обязательно делитесь. Будем обсуждать😊
#sql #задача