- Usar
COALESCE
como @Justin fornecido. -
Comfirst_value()
/last_value()
você precisa para adicionar umORDER BY
cláusula para a definição da janela ou a ordem é indefinida . Você teve sorte no exemplo, porque as linhas estão em ordem logo após a criação da tabela fictícia.
Depois de adicionarORDER BY
, o quadro de janela padrão termina na linha atual , e você precisa especializar olast_value()
call - ou reverter a ordem de classificação no quadro da janela, como demonstrado no meu primeiro exemplo.
-
Ao reutilizar uma definição de janela várias vezes, umaWINDOW
explícita cláusula simplifica muito a sintaxe:
SELECT ring, part, ARRAY[
coalesce(
lag(part) OVER w
,first_value(part) OVER (PARTITION BY ring ORDER BY part DESC))
,part
,coalesce(
lead(part) OVER w
,first_value(part) OVER w)
] AS neighbours
FROM rp
WINDOW w AS (PARTITION BY ring ORDER BY part);
Melhor ainda , reutilize a mesma definição de janela, para que o Postgres possa calcular todos os valores em uma única varredura. Para que isso funcione, precisamos definir um quadro de janela personalizado :
SELECT ring, part, ARRAY[
coalesce(
lag(part) OVER w
,last_value(part) OVER w)
,part
,coalesce(
lead(part) OVER w
,first_value(part) OVER w)
] AS neighbours
FROM rp
WINDOW w AS (PARTITION BY ring
ORDER BY part
RANGE BETWEEN UNBOUNDED PRECEDING
AND UNBOUNDED FOLLOWING)
ORDER BY 1,2;
Você pode até adaptar a definição de quadro para cada chamada de função de janela:
SELECT ring, part, ARRAY[
coalesce(
lag(part) OVER w
,last_value(part) OVER (w RANGE BETWEEN CURRENT ROW
AND UNBOUNDED FOLLOWING))
,part
,coalesce(
lead(part) OVER w
,first_value(part) OVER w)
] AS neighbours
FROM rp
WINDOW w AS (PARTITION BY ring ORDER BY part)
ORDER BY 1,2;
Pode ser mais rápido para anéis com muitas peças. Você vai ter que testar.
Fiddle SQL demonstrando todos os três com um caso de teste aprimorado. Considere os planos de consulta.
Mais sobre as definições de moldura de janela:
- No manual.
- Função de janela PostgreSQL:partição por comparação
- Consulta PostgreSQL com data máxima e mínima mais id associado por linha