PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Comment comparer la ligne actuelle avec la ligne suivante et précédente dans PostgreSQL ?

Ceci est ma solution en utilisant les WINDOW functions . J'ai utilisé le lag et lead les fonctions. Les deux renvoient une valeur d'une colonne d'une ligne en décalage par rapport à la ligne actuelle. lag revient et lead va ensuite dans le décalage.

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)

Version simplifiée :

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';

Points majeurs

  • = ANY() n'est pas nécessaire, la fonction window renvoie une seule valeur
  • certains champs redondants dans la sous-requête
  • pas besoin de trier par colonnes, que vous PARTITION BY - le ORDER BY s'applique dans partitions
  • N'utilisez pas d'identificateurs à casse mixte sans guillemets, cela ne ferait que prêter à confusion. (Mieux encore :n'utilisez pas d'identificateurs à casse mixte dans PostgreSQL jamais )