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

Como comparar a linha atual com a próxima e anterior no PostgreSQL?


Esta é a minha solução usando WINDOW functions . Eu usei o lag e lead funções. Ambos retornam um valor de uma coluna de uma linha em deslocamento da linha atual. lag volta e lead vai em seguida no deslocamento.
SELECT tokcat.text
FROM (
    SELECT text, category, chartype, lag(category,1) OVER w as previousCategory, lead(category,1) OVER w as nextCategory
    FROM token t, textBlockHasToken tb
    WHERE tb.tokenId = t.id
    WINDOW w AS (
        PARTITION BY textBlockId, sentence
        ORDER BY textBlockId, sentence, position
    )
) tokcat
WHERE 'NAME' = ANY(previousCategory)
AND 'NAME' = ANY(nextCategory)
AND 'NAME' <> ANY(category)

Versão simplificada:
SELECT text
FROM (
    SELECT text
          ,category 
          ,lag(category) OVER w as previous_cat
          ,lead(category) OVER w as next_cat
    FROM   token t
    JOIN   textblockhastoken tb ON tb.tokenid = t.id
    WINDOW w AS (PARTITION BY textblockid, sentence ORDER BY position)
    ) tokcat
WHERE  category <> 'NAME'
AND    previous_cat = 'NAME'
AND    next_cat = 'NAME';

Pontos principais

  • = ANY() não é necessário, a função window retorna um único valor
  • alguns campos redundantes na subconsulta
  • não há necessidade de ordenar por colunas, que você PARTITION BY - o ORDER BY se aplica dentro partições
  • Não use identificadores de maiúsculas e minúsculas sem aspas, isso só leva à confusão. (Melhor ainda:não use identificadores de maiúsculas e minúsculas no PostgreSQL nunca )