sql >> Databasteknik >  >> RDS >> PostgreSQL

Hur jämför man den nuvarande raden med nästa och föregående rad i PostgreSQL?

Det här är min lösning som använder WINDOW functions . Jag använde lag och lead funktioner. Båda returnerar ett värde från en kolumn från en rad i offset från den aktuella raden. lag går tillbaka och lead går nästa i 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)

Förenklad version:

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

Huvudpunkter

  • = ANY() inte behövs, returnerar fönsterfunktionen ett enda värde
  • några redundanta fält i underfrågan
  • du behöver inte beställa efter kolumner, som du PARTITION BY - BESTÄLLNING AV gäller inom partitioner
  • Använd inte identifierare med blandade skiftlägen utan att citera, det leder bara till förvirring. (Ännu bättre:använd inte identifierare med blandade skiftlägen i PostgreSQL någonsin )


  1. Anpassade formatsträngar för datum/tid som stöds av FORMAT() i SQL Server

  2. dela strängen i flera rader

  3. TSQL Prova / fånga inom transaktion eller vice versa?

  4. Introduktion till Native Dynamic SQL i Oracle Database