PostgreSQL使用数字字段连接一个int值

时间:2012-07-05 13:12:23

标签: postgresql concatenation

我想做点什么:

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

nm_cli_espace_clientnumeric(0,8).

如何轻松实现?

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:1)

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

编辑:很容易,但真的在PostgreSQL中不会很快。尽管在使用C和Java等语言编写整数类型时,这种方法的速度更快 ,但在使用int时,在PostgreSQL下的SQL似乎要慢得多,并且非常< / {>慢NUMERIC。可能是int的函数调用开销,以及使用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)

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,基于数学的方法也非常慢。显然采用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中,NUMERIC的基于数学的方法慢了200多倍,整数慢了大约50%。对于整数数学很便宜且字符串操作/内存分配很昂贵的语言来说,这是一个方便的技巧。