Postgresql 如何创建一个有N个列的表

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Postgresql 如何创建一个有N个列的表相关的知识,希望对你有一定的参考价值。


如果需要创建一个有99列的表,列名都是有规律的比如s01,s02,s03……也许你会想到如下语句

CREATE TABLE tb_sxx (
 s01 varchar(10),
 s02 varchar(10),
 s03 varchar(10),
 ……
 s99 varchar(10)
 );


有没有更快捷的方法呢?当然有了,不妨借助一下Postgresql的三个有力函数
generate_series(x,y) --生成x到y之间的值
array_agg(x) --把x值转成 如{1,2,3,4}的格式,即转成数组
array_to_string({} , ‘,‘) 把数组转成字符串,其中 ‘,‘ 是数组的分隔符


为了更直观的理解以下举例(生成一个5列的表),分步说明,如果对上述三个函数很熟悉可直接到第6步:


1.生成1到5之间的数
SELECT generate_series(1,5);

hotel=> SELECT generate_series(1,5);
 generate_series 
-----------------
               1
               2
               3
               4
               5
(5 rows)

2.把1到5的数转成数组
 SELECT array_agg(i)
FROM generate_series(1,5) AS i;

hotel=> SELECT array_agg(i)
hotel-> FROM generate_series(1,5) AS i;
  array_agg  
-------------
 {1,2,3,4,5}
(1 row)


3.加工第2步生成的数据,将格式变为{s01,s02,s03,s04,s05}
 SELECT array_agg(‘s‘ || lpad(i::text,2,‘0‘))
FROM generate_series(1,5) AS i;

hotel=> SELECT array_agg(‘s‘ || lpad(i::text,2,‘0‘))
hotel-> FROM generate_series(1,5) AS i;
       array_agg       
-----------------------
 {s01,s02,s03,s04,s05}
(1 row)

解释:
i::text 是将i转换成字符类形
lpad 是将i转换为2位,位数不足时在左边加0


4.加工第3步生成的数据,将其转换为{s01 varchar(10),s02 varchar(10),s03 varchar(10),s04 varchar(10),s05 varchar(10)}
 SELECT  array_agg(‘s‘ || lpad(i::text,2,‘0‘) || ‘ varchar(10)‘)
FROM generate_series(1,5) AS i;

hotel=>  SELECT  array_agg(‘s‘ || lpad(i::text,2,‘0‘) || ‘ varchar(10)‘) 
hotel-> FROM generate_series(1,5) AS i;
                                          array_agg                                          
---------------------------------------------------------------------------------------------
 {"s01 varchar(10)","s02 varchar(10)","s03 varchar(10)","s04 varchar(10)","s05 varchar(10)"}
(1 row)


5.加工第4步生成的数据,将其转换成字符串
 SELECT  array_to_string (
              array_agg(‘s‘ || lpad(i::text,2,‘0‘) || ‘ varchar(10)‘)
               , ‘,‘)
FROM generate_series(1,5) AS i;

hotel=> SELECT  array_to_string ( 
hotel(>               array_agg(‘s‘ || lpad(i::text,2,‘0‘) || ‘ varchar(10)‘) 
hotel(>                , ‘,‘)
hotel-> FROM generate_series(1,5) AS i;
                                 array_to_string                                 
---------------------------------------------------------------------------------
 s01 varchar(10),s02 varchar(10),s03 varchar(10),s04 varchar(10),s05 varchar(10)
(1 row)


6.最终生成建表语句
 SELECT  ‘CREATE TABLE tb_s5 ( ‘ ||
              array_to_string (
              array_agg(‘s‘ || lpad(i::text,2,‘0‘) || ‘ varchar(10)‘)
               , ‘,‘) ||
              ‘);‘
FROM generate_series(1,5) AS i;

hotel=>  SELECT  ‘CREATE TABLE tb_s5 ( ‘ ||
hotel->               array_to_string ( 
hotel(>               array_agg(‘s‘ || lpad(i::text,2,‘0‘) || ‘ varchar(10)‘) 
hotel(>                , ‘,‘) ||
hotel->               ‘);‘
hotel-> FROM generate_series(1,5) AS i;
                                                ?column?                                                
--------------------------------------------------------------------------------------------------------
 CREATE TABLE tb_s5 ( s01 varchar(10),s02 varchar(10),s03 varchar(10),s04 varchar(10),s05 varchar(10));
(1 row)

至此建表语句就生成了,复制粘贴就可以执行了,如果是psql亦可用下面的将下面的语句保存为
build_s5.psql文件,然后用psql直接执行
psql -h localhost -p 5432 -U username -f  build_s5.psql -d dbname


文件内容如下:


\a \t
 SELECT  ‘CREATE TABLE tb_s5 ( ‘ ||
              array_to_string (
              array_agg(‘s‘ || lpad(i::text,2,‘0‘) || ‘ varchar(10)‘)
               , ‘,‘) ||
              ‘);‘
FROM generate_series(1,5) AS i;
\g create_s5.sql
\i create_s5.sql


解释:
\a 关闭对齐模式
\t 关闭标行输出
\g 将查询结果输出到指定文件
\i 执行文件


本文出自 “镜子” 博客,请务必保留此出处http://383133430.blog.51cto.com/454215/1739310

以上是关于Postgresql 如何创建一个有N个列的表的主要内容,如果未能解决你的问题,请参考以下文章

Bigquery:如何将 2 个时间戳列合并为 1 个列?

尝试为其他几个列的完整地址创建一个列,但在某些地址上遇到问题

过滤N个列以获取特定值

如何在Java中导出PDF的n个列?

PostgreSQL:重用适用于虚拟表数据的函数代码

PostgreSQL:为布尔列创建索引