问题
I want to create a WINDOW in PostgreSQL and get the row_number() from a number until it appears again. As example, supposing I want to create a window from number 79 until 79 appears again and reset the counting, it must be like this:
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
How I can do this?
回答1:
Consider this:
-- 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
Produces exactly your result.
回答2:
There is always a CTE lurking somewhere ...
-- 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
;
来源:https://stackoverflow.com/questions/8250563/how-create-a-window-in-postgresql-until-the-same-value-appears-again