第二部分:数据类型

3.1 数字类型

PostgreSQL支持的数字类型有整数类型、用户指定精度类型、浮点类型、serial类型。

3.1.1 数字类型列表:


这里重点说明smallserial、serial、bigserial类型,这些是指自增serial类型,如下代码创建一张测试表,定义test_serial表的id字段类型为serial类型:


图中可以看到表定义Default列为nextval('company_02_id_seq'::regclass),现在插入数据,其中id可以不用插入,根据定义会自动生成(类似MySQL中autoincrement属性):

图中可以看到id列会自动插入连续值。

3.1.2 数字类型操作符合数据函数:
加减乘除取模运算,例如:
tt=# select 1+1,3-2,2*3,6/2,8%3;
?column? | ?column? | ?column? | ?column? | ?column?
----------+----------+---------+----------+----------
2 | 1 | 6 | 3 | 2
(1 row)
取模运算:
tt=# select mod(8,3);
mod
-----
2
(1 row)
四舍五入函数运算:
tt=# select round(10.2),round(10.6);
round | round
-------+-------
10 | 11
(1 row)
向上取整、向下取整函数运算:
tt=# select ceil(2.4),ceil(-2.4),floor(2.4),floor(-2.4);
ceil | ceil | floor | floor
------+------+-------+-------
3 | -2 | 2 | -3
(1 row)

3.2 字符类型

字符类型

3.2.2字符类型函数:
计算字符串占用字符数:
tt=# select char_length('abcde');
char_length
-------------
5
(1 row)
计算字符串占用字节数:
tt=# select octet_length('abcde');
octet_length
--------------
5
(1 row)
指定字符在字符串中的位置:
tt=# select position('a' in 'abcea');
position
----------
1
(1 row)
截取字符串子串:
tt=# select substring('abce' from 2 for 2);
substring
-----------
bc
(1 row)
拆分字符串:
tt=# select split_part('abc@123','@',2);
split_part
------------
123
(1 row)

3.3 时间/日期类型

3.3.1 字符类型列表:


例子:
tt=# select now();
now
-------------------------------
2021-03-05 05:19:23.143058+08
(1 row)
日期类型转换:
tt=# select now()::timestamp without time zone;
now
----------------------------
2021-03-05 05:20:59.151295
(1 row)
注意这里变化:没有时区

转换成data类型:
tt=# select now()::date;
now
------------
2021-03-05
(1 row)

转为没有时区的time:
tt=# select now()::time without time zone;
now
-----------------
05:23:34.217903
(1 row)

interval指时间间隔,可以是hour、day、month、year等,举例如下:
tt=# select now(),now()+interval'1 day';
now | ?column?
-------------------------------+-------------------------------
2021-03-05 05:26:01.496226+08 | 2021-03-06 05:26:01.496226+08
(1 row)
其中timestamp(精度),例如:
tt=# select now(),now()::timestamp(0);
now | now
-------------------------------+---------------------
2021-03-05 05:27:45.025553+08 | 2021-03-05 05:27:45
(1 row)

3.3.2 时间/日期操作符:
时间、日期也支持加减乘除
日期相加、如下所示:
tt=# select date '2021-03-06'+ interval'1 days';
?column?
---------------------
2021-03-07 00:00:00
(1 row)
日期相减、如下所示:
tt=# select date '2021-03-06'- interval'1 days';
?column?
---------------------
2021-03-05 00:00:00
(1 row)
日期相乘、如下所示:
tt=# select 1000*interval'1 second';
?column?
----------
00:16:40
(1 row)
日期相除、如下所示:
tt=# select interval'1 hour'/double precision '3';
?column?
----------
00:20:00
(1 row)

3.3.3 时间/日期常用函数:
显示当前时间,如下:
tt=# select current_date,current_time;
current_date | current_time
--------------+--------------------
2021-03-05 | 05:35:52.289618+08
(1 row)

另一个非常重要的函数EXTRACT函数,可以从日期、时间中抽取年、月、日、时、分、秒信息,语法如下:
tt=# select EXTRACT(year from now());
date_part
-----------
2021
(1 row)

对于timestamp类型,取月份和月份里的第几天,代码如下:
tt=# select EXTRACT(month from now()),EXTRACT(day from now());
date_part | date_part
-----------+-----------
3 | 5
(1 row)

取小时、分钟、秒,如下:
tt=# select EXTRACT(hour from now()),EXTRACT(minute from
now()),extract(second from now());
date_part | date_part | date_part
-----------+-----------+-----------
5 | 40 | 22.557332
(1 row)

取当前日期所在年份的第几周,所在年份的第几天,如下:
tt=# select EXTRACT(week from now()),EXTRACT(doy from now());
date_part | date_part
-----------+-----------
9 | 64
(1 row)

3.4 布尔类型

PostgreSQL支持的布尔类型如下:

列表

其中true状态的有效值可以是TRUE、t、true、y、yes、on、1;false状态的有效值可以是FALSE、f、false、n、no、off、0传一张表演示:
示例

查询结果如下:
结果

3.5 网络地址类型

      当存储IP地址需求的业务场景是,对于PostgreSQL并不熟悉的开发者可能会使用字符类型存储,实际上PostgreSQL提供用于存储IPv4、IPv6、MAC网络地址的专有网络地址数据类型,使用网络地址数据类型存储IP地址要优于字符类型,因为网络地址类型一方面会对数据合法性进行检查,另一方面也提供了网络地址操作符和函数,方便应用程序开发。

3.5.1 网络地址类型列表:


      inet和cidr类型存储的网络地址格式为address/y,其中address表示IPv4或IPv6网络地址,y表示网络掩码位数,如果y省略,则对于IPv4网络掩码为32,对于IPv6网络掩码为128,所以该值表示一台主机。
inet和cidr都会对数据合法进行检查,如果数据不合法会报错,如下所示:

inet和cidr存在以下差别。
1) cidr类型输出默认带子网掩码信息,而inet不一定,如下所示:
tt=# select '192.168.2.100'::cidr;
cidr
------------------
192.168.2.100/32
(1 row)

tt=# select '192.168.2.100/32'::inet;
inet
---------------
192.168.2.100
(1 row)

tt=# select '192.168.0.0/16'::inet;
inet
----------------
192.168.0.0/16
(1 row)

2) cidr类型会对IP地址和子网掩码合法性进行检查,而inet不会,如下所示:
tt=# select '192.168.2.0/8'::cidr;
ERROR: invalid cidr value: "192.168.2.0/8"
LINE 1: select '192.168.2.0/8'::cidr;
^
DETAIL: Value has bits set to right of mask.

tt=# select '192.168.2.0/8'::inet;
inet
---------------
192.168.2.0/8
(1 row)

tt=# select '192.168.2.0/24'::cidr;
cidr
----------------
192.168.2.0/24
(1 row)

从以上演示可以看出cidr要比inet网络类型更加严谨。

3.5.2 网络地址操作符:

3.5.3 网络地址函数:
取IP地址,返回文本格式,如下所示:
tt=# select host(cidr '192.168.1.0/24');
host
-------------
192.168.1.0
(1 row)

取IP地址和子网掩码信息,返回文本格式,如下所示:
tt=# select text(cidr '192.168.1.0/24');
text
----------------
192.168.1.0/24
(1 row)

取网络地址子网掩码,返回文本格式,如下所示:
tt=# select netmask(cidr '192.168.1.0/24');
netmask
---------------
255.255.255.0
(1 row)

3.6 数组类型

        PostgreSQL支持一维数组和多维数组,常用的数组类型为数字类型数组和字符型数组,也支持枚举类型、复合类型数组。

3.6.1 数组类型定义:
先来看数组类型的定义,创建表时在字段数据类型后面加方括号"[]"即可定义数组类型,如下所示:
tt=# create table test_array(id integer,array_i integer[],array_t text[]);
CREATE TABLE
以上integer[]表示integer类型一维数组,text[]表示text类型一维数组。

3.6.2 数组类型值输入:
数组类型的插入有两种方式,第一种方式使用花括号方式,如下所示:
'{val1 delim val2 delim...}'
将数组元素用花括号"{}"包围并用delim分隔符分开,数组元素值通常可以用双引号引用,delim分隔符通常为逗号,如下所示:
tt=# select '{1,2,3}';
?column?
----------
{1,2,3}
(1 row)

往test_array表中插入一条数据,如下:
tt=# insert into test_array(id,array_i,array_t) values(1,'{1,2,3}','{"a","b","c"}');
INSERT 0 1

数组类型插入的第二种方式使用ARRAY关键字,如下所示:
tt=# select array[1,2,3];
array
---------
{1,2,3}
(1 row)

往test_array1表中插入一条数据,如下:
tt=# insert into test_array1(id,array_i,array_t)
values(2,array[4,5,6],array['d','e','y']);
INSERT 0 1

表test_arrya1中的数据为:
tt=# select * from test_array1;
id | array_i | array_t
----+---------+---------
2 | {4,5,6} | {d,e,y}
(1 row)

3.6.3 查询数组元素:
如果想要查询数组所有元素值,只需查询数组名称即可,如下所示:
tt=# select array_i from test_array1 where id = 2;
array_i
---------
{4,5,6}
(1 row)
数据元素通过"[]"的方式,数据下标写在方括号内,范围编号为1到n,n为数组长度,如下所示:
tt=# select array_i[1],array_t[3] from test_array1 where id = 2;
array_i | array_t
---------+---------
4 | y
(1 row)

3.6.4 元素的追加、删除、更新:
追加有两种方式,如下:
tt=# select array_append(array[1,2,3],4),array[1,2,3]||4;
array_append | ?column?
--------------+-----------
{1,2,3,4} | {1,2,3,4}
(1 row)

删除用array_remove函数,如下所示:
tt=# select array[1,2,3,4],array_remove(array[1,2,3,4],4);
array | array_remove
-----------+--------------
{1,2,3,4} | {1,2,3}
(1 row)

修改,如下所示:
tt=# update test_array1 set array_i[3] = 10 where id = 2;
UPDATE 1
tt=# select * from test_array1;
id | array_i | array_t
----+----------+---------
2 | {4,5,10} | {d,e,y}
(1 row)

3.6.5 数组操作符:

3.6.6 数组函数:
添加、删除元素:
tt=# select array_append(array[1,2],4),array_remove(array[4,5,6],4);
array_append | array_remove
--------------+--------------
{1,2,4} | {5,6}
(1 row)

获取数组维度:
tt=# select array_ndims(array[1,2,4]),array_ndims(array[[1,2,3],[4,5,6]]);
array_ndims | array_ndims
-------------+-------------
1 | 2
(1 row)

获取数组长度、第一次出现的位置:
tt=# select array_length(array[1,2,3,4],1);
array_length
--------------
4

tt=# select array_position(array[1,2,3,4,3],'3');
array_position
----------------
3
(1 row)

字符串替换:
tt=# select array_replace(array[1,2,3,5],5,4);
array_replace
---------------
{1,2,3,4}
(1 row)

将数组元素输出到字符串,将null替换为4,5:
tt=# select array_to_string(array[1,2,3,null,6],',','4,5');
array_to_string
-----------------
1,2,3,4,5,6
(1 row)

3.9 数据类型转换

前面几小节介绍了 PostgreSQL 常规数据类型和非常规数据类型,这一小节将介绍数据
类型转换, PostgreSQL 数据类型转换主要有三种方式 : 通过格式化函 数、 CAST 函 数、..
操作符,下面分别介绍 。

3.9.1 通过格式化函数进行转换

3.9.2 通过CAST函数进行转换
将varchar类型转换为text类型,如下所示:
tt=# select 'abc',cast('abc' as text);
?column? | text
----------+------
abc | abc
(1 row)

将varchar类型转换为int4类型,如下所示:
tt=# select cast('123' as int4),cast('123' as int);
int4 | int4
------+------
123 | 123
(1 row)

3.9.3 通过操作符::进行转换
将int类型转换为numeric,如下所示:
tt=# select 1::int4,1/3::numeric;
int4 | ?column?
------+------------------------
1 | 0.33333333333333333333
(1 row)

另一个例子,通过 SQL 查询给定表的字段名 称,先根据表名在系统表 pg_class 找到表
的 OID ,其中 OID 为隐藏的系统宇段:
tt=# select oid,relname from pg_class where relname = 'test_json1';
oid | relname
-------+------------
16454 | test_json1
(1 row)

之后根据 test_json 1 表的 OID , 在 系 统表 pg_attribute 中根据 attrelid ( 即 表 的 OID )找
到表的字段,如下所示:
tt=# select attname from pg_attribute where attrelid='16454' and attnum>0;
attname
---------
id
name
(2 rows)

上述操作需通过两步完成,但通过类型转换可一步到位 , 如下所示 :
tt=# select attname from pg_attribute where attrelid='test_json1'::regclass and ``````attnum>0;
attname
---------
id
name
(2 rows)

这节介绍了三种数据类型转换方法,第-种方法兼容性相对较好,第三种方法用法简捷。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,492评论 6 513
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,048评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,927评论 0 358
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,293评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,309评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,024评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,638评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,546评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,073评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,188评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,321评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,998评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,678评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,186评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,303评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,663评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,330评论 2 358

推荐阅读更多精彩内容