- Usar
COALESCE
como lo proporcionó @Justin. -
Con
first_value()
/last_value()
usted necesita para agregar unORDER BY
cláusula a la definición de la ventana o el orden es indefinido . Simplemente tuviste suerte en el ejemplo, porque las filas están en orden justo después de crear la tabla ficticia.
Una vez que agregasORDER BY
, el marco de ventana predeterminado termina en la fila actual , y necesita un caso especial dellast_value()
llamar - o revertir el orden de clasificación en el marco de la ventana como se muestra en mi primer ejemplo. -
Al reutilizar una definición de ventana varias veces, una
WINDOW
explícita cláusula simplifica mucho la sintaxis:
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);
Mejor aún , reutilice la misma definición de ventana, para que Postgres pueda calcular todos los valores en un solo escaneo. Para que esto funcione, necesitamos definir un marco de ventana 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;
Incluso puede adaptar la definición del marco para cada llamada de función de ventana:
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;
Podría ser más rápido para anillos con muchas partes. Tendrás que probar.
Violín SQL demostrando los tres con un caso de prueba mejorado. Considere los planes de consulta.
Más sobre definiciones de marcos de ventana:
- En el manual.
- Función de ventana de PostgreSQL:partición por comparación
- Consulta de PostgreSQL con fecha máxima y mínima más identificación asociada por fila