2

I would like to do something like :

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

nm_cli_espace_client is numeric(0,8).

How to make it easy?

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)

您的问题与此相同:concat two int values in postgresql

于 2012-07-05T13:27:44.303 回答
1

正如@vyegorov 所展示的那样,可以通过文本连接来将数字前缀到数字上,但它也很容易作为数学运算来完成。

编辑:在 PostgreSQL 中很容易,但实际上并不快。尽管这种方法在使用 C 和 Java 等语言对整数类型进行编程时要快得多,但在使用 int 时在PostgreSQL下的 SQL 中似乎要慢得多,而对于NUMERIC. 可能是整数的函数调用开销,以及使用数字时数字数学的一般缓慢。无论如何,您最好按照@vyegorov 的回答将字符串连接为字符串。

我将保留其余的答案以供大笑;这是一个很好的例子,说明了为什么您应该测试解决问题的多种方法。

一种数学方法是:

nm_cli_espace_client = 9*pow(10,1+floor(log(nm_cli_pe))) +  nm_cli_espace_client;

可能有比这更聪明的方法。它所做的基本上是产生 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)

对比

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 回答