Membangun data pengujian Anda, tetapi ini berfungsi dengan data arbitrer. Ini bekerja dengan sejumlah elemen dalam string.
Daftarkan jenis komposit yang terdiri dari satu text
dan satu integer
nilai sekali per database. Saya menyebutnya ai
:
CREATE TYPE ai AS (a text, i int);
Caranya adalah dengan membentuk array ai
dari setiap nilai dalam kolom.
regexp_matches()
dengan pola (\D*)(\d*)
dan g
opsi mengembalikan satu baris untuk setiap kombinasi huruf dan angka. Ditambah satu baris menjuntai yang tidak relevan dengan dua string kosong '{"",""}'
Memfilter atau menekannya hanya akan menambah biaya. Gabungkan ini ke dalam array, setelah mengganti string kosong (''
) dengan 0
dalam integer
komponen (sebagai ''
tidak dapat dilemparkan ke integer
).
NULL
nilai urutkan terlebih dahulu - atau Anda harus membuat huruf besar-kecil - atau gunakan seluruh Shebang dalam STRICT
berfungsi seperti yang diusulkan @Craig.
Postgres 9.4 atau lebih baru
SELECT data
FROM alnum
ORDER BY ARRAY(SELECT ROW(x[1], CASE x[2] WHEN '' THEN '0' ELSE x[2] END)::ai
FROM regexp_matches(data, '(\D*)(\d*)', 'g') x)
, data;
db<>main biola di sini
Postgres 9.1 (jawaban asli)
Diuji dengan PostgreSQL 9.1.5, di mana regexp_replace()
memiliki perilaku yang sedikit berbeda.
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
Tambahkan regexp_replace (left(data, 1), '[1-9]', '0')
sebagai ORDER BY
pertama item untuk menangani digit utama dan string kosong.
Jika karakter khusus seperti {}()"',
dapat terjadi, Anda harus menghindarinya.
Saran @Craig untuk menggunakan ROW
ekspresi menangani itu.
BTW, ini tidak akan dijalankan di sqlfiddle, tetapi bisa di cluster db saya. JDBC tidak sanggup. sqlfiddle mengeluh:
Metode org.postgresql.jdbc3.Jdbc3Array.getArrayImpl(long,int,Map) belum diterapkan.
Ini telah diperbaiki:http://sqlfiddle.com/#!17/fad6e/1