PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Come confrontare la riga corrente con la riga successiva e precedente in PostgreSQL?

Questa è la mia soluzione utilizzando WINDOW functions . Ho usato il lag e lead funzioni. Entrambi restituiscono un valore da una colonna da una riga in offset dalla riga corrente. lag torna indietro e lead va avanti nell'offset.

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)

Versione semplificata:

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

Punti principali

  • = ANY() non è necessario, la funzione finestra restituisce un singolo valore
  • alcuni campi ridondanti nella sottoquery
  • non c'è bisogno di ordinare per colonne, che tu PARTITION BY - l'ORDER BY si applica entro partizioni
  • Non utilizzare identificatori di maiuscole miste senza virgolette, crea solo confusione. (Meglio ancora:non utilizzare identificatori di casi misti in PostgreSQL mai )