2011-11-23 42 views
0

我想在PostgreSQL中創建一個WINDOW,並從數字中獲取row_number(),直到它再次出現。作爲例子,假設我要創建79個窗口,直到79再次出現,並重置計數,它必須是這樣的:如何在PostgreSQL中創建一個WINDOWS直到再次出現相同的值?

number  must be  row_number number 
    50        ?  50 
    79        1  79 
    85        2  85 
    74        3  74 
    14        4  14 
    79        1  79 
    46        2  46 
    85        3  85 
    79        1  79 
    45        2  45 

我怎樣才能做到這一點?

回答

1

考慮一下:

-- temporary test table 
CREATE TEMP TABLE tbl (id serial, nr int); 
INSERT INTO tbl(nr) VALUES 
(50),(79),(85),(74),(14) 
,(79),(46),(85),(79),(45); 

SELECT id, nr 
     ,CASE WHEN grp > 0 THEN 
      row_number() OVER (PARTITION BY grp ORDER BY id)::text 
     ELSE '?' END AS rn  
FROM (
    SELECT id, nr 
      ,sum(CASE WHEN nr = 79 THEN 1 ELSE 0 END) OVER (ORDER BY id) AS grp 
    FROM tbl) x 
-- WHERE grp > 0 -- to exclude numbers before the first 79 

正好產生你的結果。

+0

太棒了!非常感謝,這將有助於解決我遇到的其他問題。 –

1

總有一個CTE潛伏的地方......

-- temporary test table 
-- (thanks for that) 
CREATE TEMP TABLE tbl (id serial, nr int); 
INSERT INTO tbl(nr) VALUES 
(50),(79),(85),(74),(14) 
,(79),(46),(85),(79),(45); 

-- EXPLAIN ANALYZE 
WITH next AS (
    SELECT t1.id AS id 
     , t2.id AS next 
    FROM tbl t1 
    JOIN tbl t2 ON (t2.nr = t1.nr AND t2.id > t1.id) 
     WHERE NOT EXISTS (SELECT * 
      FROM tbl nx 
      WHERE nx.nr = t1.nr 
      AND nx.id > t1.id 
      AND nx.id < t2.id 
      ) 
    ) 
SELECT t0.id 
     , t0.nr 
     , next.next AS next 
FROM tbl t0 
LEFT JOIN next ON (next.id=t0.id) 
ORDER BY id 
    ; 
+0

Drive-by-CTE-ing? :) –

+0

這是一種生活方式!順便說一句,它似乎比你的更具有普遍性,它具有內置的79常數。窗口只用來縮小你的視野,而不是擴大它;-) – wildplasser

+0

這不完全是OP想要的(他希望排名,可能提取n-grams),但我喜歡下一個指針。如果我找到時間,我會找到一種方法來編寫ngram並用直方圖報告它們。會在外循環中產生大量的排序。 – wildplasser

相關問題