web-dev-qa-db-ja.com

PostgreSQLのフィールドから数値を抽出します

Postgres 8.4にvarchar型のpo_number列を持つテーブルがあります。英数字といくつかの特殊文字を保存します。文字[/alpha/?/$/encoding/.]を無視して、列に数字が含まれているかどうかを確認したい。数値の場合、出力フィールドpo_number_newは数値フィールドなので、数値として型キャストするか、nullを渡す必要があります。

以下に例を示します。

example

SQL Fiddle。

私はこの声明にうんざりしました:

select 
(case when  regexp_replace(po_number,'[^\w],.-+\?/','') then po_number::numeric
else null
end) as po_number_new from test

しかし、明示的なキャストでエラーが発生しました:

error

12
user1538020

単に:

SELECT NULLIF(regexp_replace(po_number, '\D','','g'), '')::numeric AS result
FROM   tbl;

\Dは、「数字ではない」のクラスの略記である。
そして、4番目のパラメーター'g'(「グローバル」の場合)allオカレンスを置換します。
マニュアルの詳細

しかし、なぜPostgres 8.4なのでしょうか? 最新バージョンへのアップグレードを検討してください。

古いバージョンの落とし穴を考慮してください:

26

次のようなものが欲しいと思います:

select (case when regexp_replace(po_number, '[^\w],.-+\?/', '') ~ '^[0-9]+$'
             then regexp_replace(po_number, '[^\w],.-+\?/', '')::numeric
        end) as po_number_new 
from test;

つまり、文字列after置換で変換を行う必要があります。

注:これは、「数値」が単なる数字のストリングであると想定しています。

2
Gordon Linoff

po_numberフィールドに数字が含まれているかどうかを判断するために使用するロジックは、数字を削除しようとするとその長さが短くなるということです。

その場合、すべての非数字([^\d])をpo_number列から削除する必要があります。それ以外の場合は、NULLが返されます。

select case when char_length(regexp_replace(po_number, '\d', '', 'g')) < char_length(po_number)
            then regexp_replace(po_number, '[^0-9]', '', 'g')
            else null
       end as po_number_new
from test
1
Tim Biegeleisen