복붙노트

[SQL] 어떻게 PostgreSQL을에 다음 및 이전 행이 현재의 행을 비교?

SQL

어떻게 PostgreSQL을에 다음 및 이전 행이 현재의 행을 비교?

나는 다음 또는 이전 행이 어떤 논리 비교를하고 SQL 쿼리의 결과를 검색하는 방법을 알고 싶어요. 나는 PostgreSQL을 사용하고 있습니다.

예 나는 두 가지 속성 (주문 위치와 임의의 숫자) 내 데이터베이스에서 테이블을 가정하면, 난 숫자 사이에 홀수 번호를 검색합니다. 이걸 어떻게 할 수 있습니까?

실제 사용 나는 둘 사이에 카테고리 이름을 (그리고 단어가 이름이 아닌) 다른 단어 단어를 찾고 싶어요. 순서는 문장과 위치에 의해 제공됩니다.

편집하다 나는 PostgreSQL을의 창 기능 쿼리를하는 것보다 이런 종류의 문제에 대한 최적의 솔루션이 있다면 알고 싶어요. 나는 그들에 대해 들었지만, 사용되지 않습니다.

해결법

  1. ==============================

    1.이 창 기능을 사용하여 내 솔루션입니다. 나는 지연과 리드 기능을 사용했다. 모두 현재 행 오프셋의 행의 열에서 값을 반환합니다. 지연은 돌아 간다 리드는 다음 오프셋 (offset)에 들어간다.

    이 창 기능을 사용하여 내 솔루션입니다. 나는 지연과 리드 기능을 사용했다. 모두 현재 행 오프셋의 행의 열에서 값을 반환합니다. 지연은 돌아 간다 리드는 다음 오프셋 (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)
    

    단순화 된 버전 :

    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';
    
  2. ==============================

    2.이 주소에 최적의 솔루션을 찾을 수 있습니다 :

    이 주소에 최적의 솔루션을 찾을 수 있습니다 :

    http://blog.sqlauthority.com/2013/09/25/sql-server-how-to-access-the-previous-row-and-next-row-value-in-select-statement-part-4/

    SQL 서버 2012 이후 버전에 대한 질의 1 :

    SELECT
    LAG(p.FirstName) OVER(ORDER BY p.BusinessEntityID) PreviousValue,
        p.FirstName,
        LEAD(p.FirstName) OVER(ORDER BY p.BusinessEntityID) NextValue
    FROM Person.Person p
    GO
    

    SQL 서버 2005 + 및 이후 버전에 대한 질의 2 :

    WITH CTE AS(
        SELECT rownum = ROW_NUMBER() OVER(ORDER BY p.BusinessEntityID),
        p.FirstName FROM Person.Person p
    )
    SELECT
    prev.FirstName PreviousValue,
        CTE.FirstName,
        nex.FirstName NextValue
    FROM CTE
    LEFT JOIN CTE prev ON prev.rownum = CTE.rownum - 1
    LEFT JOIN CTE nex ON nex.rownum = CTE.rownum + 1
    GO
    
  3. ==============================

    3.이 작업을해야합니다 :

    이 작업을해야합니다 :

    SELECT w1.word AS word_before, w.word, w2.word AS word_after
    FROM   word w
    JOIN   word w1 USING (sentence)
    JOIN   word w2 USING (sentence)
    WHERE  w.category <> 'name'
    AND    w1.pos = (w.pos - 1)
    AND    w1.category = 'name'
    AND    w2.pos = (w.pos + 1)
    AND    w2.category = 'name'
    

    귀하의 추가 질문에 대답하기 : 아니, 윈도우 함수는이 경우에 특히 유용하지 않을 것, 자기 조인 여기에 마법의 단어가 없습니다.

    편집하다: 나는 그렇군요. 레나토는 기능이 지연 창 (), 납 ()와 멋진 솔루션을 보여줍니다. 미묘한 차이를 참고 :

    많은 경우에 (같은 아마 손에서 하나?) 두 버전 모두 동일한 결과로 이어집니다. 아이디 공간의 차이로 다른 결과가있을 것입니다.

  4. from https://stackoverflow.com/questions/7974866/how-to-compare-the-current-row-with-next-and-previous-row-in-postgresql by cc-by-sa and MIT license