私は次のようなことをしたいと思います:
update cli_pe set nm_cli_espace_client = 9 || nm_cli_espace_client
where nm_cli_pe = 7006488
nm_cli_espace_client
はnumeric(0,8).
それを簡単にする方法は?
私は次のようなことをしたいと思います:
update cli_pe set nm_cli_espace_client = 9 || nm_cli_espace_client
where nm_cli_pe = 7006488
nm_cli_espace_client
はnumeric(0,8).
それを簡単にする方法は?
UPDATE cli_pe
SET nm_cli_espace_client = '9' || CAST(nm_cli_espace_client AS text)
WHERE nm_cli_pe = 7006488;
結果の数値が必要な場合は、CAST
結果を元に戻します。
... SET nm_cli_espace_client =
CAST('9' || CAST(nm_cli_espace_client AS text) AS integer)
あなたの質問はこれと同じです:postgresqlの2つのint値を連結します
@vyegorovが示したように、数字の前置はテキストによる連結によって行うことができますが、数学演算としても簡単に行うことができます。
編集:簡単ですが、PostgreSQLではそれほど速くはありません。このアプローチは、整数型のCやJavaなどの言語でプログラミングする場合ははるかに高速ですが、intを使用する場合はPostgreSQLのSQLでかなり遅くなり、。の場合は非常に遅くなりNUMERIC
ます。おそらく、intの関数呼び出しのオーバーヘッドと、数値を操作するときの数値計算の一般的な速度低下です。いずれにせよ、@vyegorovの回答に従って文字列として連結する方がよいでしょう。
残りの答えは笑いのために保存しておきます。これは、問題に対する複数のアプローチをテストする必要がある理由の非常に良い例です。
数学的アプローチは次のとおりです。
nm_cli_espace_client = 9*pow(10,1+floor(log(nm_cli_pe))) + nm_cli_espace_client;
おそらくそれよりも賢い方法があります。基本的には、加算される数値より1桁多い10の累乗を生成し、それを入力に乗算します。
regress=# SELECT (pow(10,1+floor(log( 7006488 ))) * 9) + 7006488;
?column?
---------------------------
97006488.0000000000000000
(1 row)
これを数学的に指摘するためのよりスマートな方法が欲しいです。きっとあると思います。
とにかく、PostgreSQLではこれを実行したくないことがわかりました。整数型の場合、少し遅くなります。
regress=# explain analyze select ('9'||x::text)::int from testtab;
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------
Seq Scan on testtab (cost=0.00..26925.00 rows=1000000 width=4) (actual time=0.026..293.120 rows=1000000 loops=1)
Total runtime: 319.920 ms
(2 rows)
vs
regress=# explain analyze select 9*pow(10,1+floor(log(x)))+x from testtab;
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------
Seq Scan on testtab (cost=0.00..34425.00 rows=1000000 width=4) (actual time=0.053..443.134 rows=1000000 loops=1)
Total runtime: 470.587 ms
(2 rows)
タイプでNUMERIC
は、テキストアプローチはあまり変わりません。
regress=# explain analyze select ('9'||x::text)::int from testtab;
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------
Seq Scan on testtab (cost=0.00..17467.69 rows=579675 width=32) (actual time=0.039..368.980 rows=1000000 loops=1)
Total runtime: 396.376 ms
(2 rows)
しかし、対数を取った後にに変換NUMERIC
しても、数学ベースのアプローチは恐ろしく遅いです。int
明らかに、aの対数を取るのは遅いですが、驚くことではありませんが、これNUMERIC
ほど遅いとは思っていませんでした。
regress=# explain analyze select 9*pow(10,1+floor(log(x)::int))+x from testtab;
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------
Seq Scan on testtab (cost=0.00..18916.88 rows=579675 width=32) (actual time=0.253..86740.383 rows=1000000 loops=1)
Total runtime: 86778.511 ms
(2 rows)
短いバージョン:テキストの連結によってそれを行います。(PostgreSQL)SQLでは、数学ベースのアプローチは、の場合は200倍以上NUMERIC
遅く、整数の場合は約50%遅くなります。ただし、整数演算が安価で、文字列操作/メモリ割り当てが高価な言語では便利なトリックです。