2

私は次のようなことをしたいと思います:

update cli_pe set nm_cli_espace_client = 9 || nm_cli_espace_client
 where nm_cli_pe = 7006488 

nm_cli_espace_clientnumeric(0,8).

それを簡単にする方法は?

4

2 に答える 2

2
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値を連結します

于 2012-07-05T13:27:44.303 に答える
1

@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%遅くなります。ただし、整数演算が安価で、文字列操作/メモリ割り当てが高価な言語では便利なトリックです。

于 2012-07-05T15:22:56.193 に答える