I have the following sample data for a particular column symbol for sample table.
(Update:) The data is not in a regular pattern. Number may occur at any place in be
PostgreSQL doesn't offer a number-aware collation that can do "humanized" sorts like "1A, 2A, 3A, ... 10A, 11A, ...". It relies on the operating system for collation, and I'm not aware of any OS that exposes such a collation to applications.
To do this, you need to split the text according to a pattern and order by the pattern parts, probably using regexp_matches.
CREATE TABLE Table1 ("symbol" text);
INSERT INTO Table1 ("symbol") VALUES
('COL4A1'),('COL4A3'),('COL8A2'),('COL2A1'),
('COL12A1'),('COL12A1'),('COL16A1'),('COL19A1');
WITH matched(symbol, symbol_parts) AS (
SELECT symbol, regexp_matches(symbol, '(\D*)(\d+)(\D+)(\d+)')
FROM Table1
)
SELECT symbol
FROM matched
ORDER BY symbol_parts[1], symbol_parts[2]::integer,
symbol_parts[3], symbol_parts[4]::integer;
CREATE OR REPLACE FUNCTION pad_numbers(text)
RETURNS text AS
$BODY$
SELECT regexp_replace(
regexp_replace(
regexp_replace(
regexp_replace(
$1,
E'(^|\\D)(\\d{1,3}($|\\D))', E'\\1000\\2', 'g'
), E'(^|\\D)(\\d{4,6}($|\\D))', E'\\1000\\2', 'g'
), E'(^|\\D)(\\d{7}($|\\D))', E'\\100\\2', 'g'
), E'(^|\\D)(\\d{8}($|\\D))', E'\\10\\2', 'g'
);
$BODY$
LANGUAGE 'sql' VOLATILE;
select symbol from sample order by pad_numbers(symbol) asc