Assuming the leading part is a single character. Hence the expression right(data, -1)
works to extract the group name. Adapt to your actual prefix.
The solution uses two window functions, which can't be nested. So we need a subquery or a CTE.
SELECT id, data
, COALESCE(first_value(grp) OVER (PARTITION BY grp_nr ORDER BY id), '0') AS grp
FROM (
SELECT *, NULLIF(right(data, -1), '') AS grp
, count(NULLIF(right(data, -1), '')) OVER (ORDER BY id) AS grp_nr
FROM tbl
) sub;
Produces your desired result exactly.
NULLIF(right(data, -1), '')
to get the effective group name or NULL
if none.
count()
only counts non-null values, so we get a higher count for every new group in the subquery.
In the outer query, we take the first grp
value per grp_nr
as group name and default to '0' with COALESCE
for the first group without name (which has a NULL
as group name so far).
We could use min()
or max()
as outer window function as well, since there is only one non-null value per partition anyway. first_value()
is probably cheapest since the rows are sorted already.
Note the group name grp
is data type text
. You may want to cast to integer, if those are clean (and reliably) integer numbers.