Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Building on your test data, but this works with arbitrary data:</p> <pre><code>CREATE TYPE ai AS (a text, i int); -- Could also be a table or even a temp table SELECT data FROM ( SELECT ctid, data, regexp_matches(data, '(\D*)(\d*)', 'g') AS x FROM alnum ) x GROUP BY ctid, data -- ctid as stand-in for a missing pk ORDER BY regexp_replace (left(data, 1), '[0-9]', '0') , array_agg(ROW(x[1], CASE x[2] WHEN '' THEN '0' ELSE x[2] END)::ai) , data -- for special case of trailing 0 </code></pre> <p>Tested with PostgreSQL 9.1.5.</p> <ul> <li><p>The trick is to form an array of <code>ai</code> - <code>ai</code>being a composite type consisting of a <code>text</code> and an <code>integer</code> column. This works with a <em>varying number</em> of elements.</p></li> <li><p>regexp_matches() with the pattern <code>(\D*)(\d*)</code> and the <code>g</code> option returns one row for every combination of letters and numbers, plus one row at the end. With leading digits, we get an empty element at the start for the letter part.</p></li> <li><p>Add <code>regexp_replace (left(data, 1), '[0-9]', '0')</code> as first <code>ORDER BY</code> item to take care of leading digits and empty strings.</p></li> <li><p>Replace empty Strings with <code>0</code> for the <code>integer</code> part .</p></li> </ul> <p><strike>- If special characters like <code>{}()"',</code> can occur, you'd have to escape those accordingly.</strike></p> <ul> <li><p>@Craig's suggestion to use a <code>ROW</code> expression takes care of that.</p></li> <li><p>If <code>NULL</code> can occur, you'd have to special case it - ore use the whole shebang in a <code>STRICT</code> function like @Craig proposes.</p></li> </ul> <p>BTW, this won't execute in sqlfiddle, but it does in my db cluster. JDBC is not up to it. sqlfiddle complains:</p> <blockquote> <p>Method org.postgresql.jdbc3.Jdbc3Array.getArrayImpl(long,int,Map) is not yet implemented.</p> </blockquote>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload