PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Como usar uma estrutura de dados em anel em funções de janela

  • Usar COALESCE como @Justin fornecido.

  • Com first_value() / last_value() você precisa para adicionar um ORDER 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 adicionar ORDER BY , o quadro de janela padrão termina na linha atual , e você precisa especializar o last_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, uma WINDOW 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