Обрабатывать смежные дубликаты значений сложно. Вы не указываете, как вы хотите, чтобы они обрабатывались. Если вам нужно только первое такое значение, то фильтрация работает:
Для локальных минимумов:
SELECT Row, date, f0 AS minimal
FROM (SELECT t.*,
LEAD(f0) OVER (ORDER BY DATE) as f0_lead
FROM (SELECT t.*,
LAG(f0) OVER (ORDER BY date) AS f0_lag
FROM `project.dataset.table` t
) t
WHERE f0_lag IS NULL or f0_lag <> f0
) t
WHERE (f0 < f0_lag or f0_lag is null) and
(f0 < f0_lead or f0_lead is null);
Или, если хотите, вы можете упростить сравнения:
SELECT Row, date, f0 AS minimal
FROM (SELECT t.*,
LEAD(f0) OVER (ORDER BY DATE) as f0_lead
FROM (SELECT t.*,
LAG(f0) OVER (ORDER BY date) AS f0_lag
FROM t
) t
WHERE f0_lag IS NULL or f0 < f0_lag
) t
WHERE f0 < f0_lead or f0_lead is null;
Локальные максимумы могут следовать той же логике с изменением <
с на >
с.
Здесь - это скрипта db <> (которая использует Postgres, но это не имеет значения).
EDIT:
Возврат всех минимумов / максимумов подряд более сложен. Следующие работы в BigQuery:
WITH t AS (
SELECT 1 AS Row, '2017-01-19' AS date, 0.3904 AS f0 UNION ALL
SELECT 2, '2017-02-04', 0.3149 UNION ALL
SELECT 2.5, '2017-02-05', 0.3149 UNION ALL
SELECT 3, '2017-03-24', 0.3302 UNION ALL
SELECT 4, '2017-04-09', 0.5339 UNION ALL
SELECT 5, '2017-05-11', 0.7753 UNION ALL
SELECT 6, '2017-05-27', 0.8539 UNION ALL
SELECT 7, '2017-09-16', 0.8803 UNION ALL
SELECT 7.5, '2017-09-17', 0.8803 UNION ALL
SELECT 7.7, '2017-09-18', 0.8803 UNION ALL
SELECT 8, '2017-10-02', 0.8570 UNION ALL
SELECT 9, '2017-11-03', 0.7744 UNION ALL
SELECT 10, '2017-11-19', 0.6092 UNION ALL
SELECT 11, '2017-12-05', 0.5785
)
SELECT t.*
FROM (SELECT t.*,
MAX(f0_lag) OVER (PARTITION BY grp) as grp_f0_lag,
MAX(f0_lead) OVER (PARTITION BY grp) as grp_f0_lead
FROM (SELECT t.*,
COUNTIF(f0_lag <> f0) OVER (ORDER BY DATE) as grp,
LEAD(f0) OVER (ORDER BY DATE) as f0_lead
FROM (SELECT t.*,
LAG(f0) OVER (ORDER BY date) AS f0_lag
FROM t
) t
) t
) t
WHERE (f0 < grp_f0_lag or grp_f0_lag is null) and
(f0 < grp_f0_lead or grp_f0_lead is null) ;
По сути, это идентифицирует группы смежных значений. Затем он распространяет максимальные значения lag()
и lead()
по группе (для максимума вы хотите распространить минимальные значения).
Вся группа затем обрабатывается как единое целое и в наборе результатов.