PostGreSQL语法及高级功能

1 createdb

## 首先查看help
root@dd50f020b9f4:/# createdb --help
createdb creates a PostgreSQL database.Usage:createdb [OPTION]... [DBNAME] [DESCRIPTION]Options:
## 指定表空间-D, --tablespace=TABLESPACE  default tablespace for the database
## 数据库名-e, --echo                   show the commands being sent to the server
## 编码-E, --encoding=ENCODING      encoding for the database
## 指定用于此数据库的本地化设置## 数据库区域设置-l, --locale=LOCALE          locale settings for the database## 数据库LC_COLLATE设置--lc-collate=LOCALE      LC_COLLATE setting for the database## 数据库LC_CTYPE设置--lc-ctype=LOCALE        LC_CTYPE setting for the database
## 属于哪个用户-O, --owner=OWNER            database user to own the new database
## 指定创建此数据库的模板数据库-T, --template=TEMPLATE      template database to copy-V, --version                output version information, then exit-?, --help                   show this help, then exitConnection options:
## 主机名-h, --host=HOSTNAME          database server host or socket directory
## 端口号-p, --port=PORT              database server port
## 登录用户名-U, --username=USERNAME      user name to connect as
## 不需要指定密码-w, --no-password            never prompt for password
## 输入密码-W, --password               force password prompt
## 备用维护数据库--maintenance-db=DBNAME      alternate maintenance databaseBy default, a database with the same name as the current user is created.Report bugs to <pgsql-bugs@postgresql.org>.

1.1 为新创建的数据库指定表空间:

##1.查看已存在表空间
postgres=# \dbList of tablespacesName    |  Owner   | Location
------------+----------+----------pg_default | postgres |pg_global  | postgres |
(2 rows)
##2.创建新的表空间,并指定位置
##2.1没有操作权限
postgres=# create tablespace zxy location '/data/postgres/dbspace';
ERROR:  could not set permissions on directory "/data/postgres/dbspace": Operation not permitted
##2.2给postgres用户该目录的操作权限
root@dd50f020b9f4:/# chown postgres /data/postgres/dbspace/
##2.3操作成功
postgres=# create tablespace zxy location '/data/postgres/dbspace';
CREATE TABLESPACE
##2.4查看路径生成表空间文件
root@dd50f020b9f4:/# ls /data/postgres/dbspace/
PG_9.4_201409291
root@dd50f020b9f4:/#
##2.5查看表空间
postgres=# \dbList of tablespacesName    |  Owner   |        Location
------------+----------+------------------------pg_default | postgres |pg_global  | postgres |zxy        | postgres | /data/postgres/dbspace
(3 rows)

1.2 createdb 并指定tablespace

## 指定登录名,端口号,属于者,新建数据库名称,tablespace
root@dd50f020b9f4:/# createdb -U postgres -p5432 -O postgres -e dbzxy -D zxy
SELECT pg_catalog.set_config('search_path', '', false)
CREATE DATABASE dbzxy OWNER postgres TABLESPACE zxy;

2 psql


root@dd50f020b9f4:/# psql --help
psql is the PostgreSQL interactive terminal.Usage:psql [OPTION]... [DBNAME [USERNAME]]General options:
## 执行SQL命令
## psql -c 'select * from ods.ods_gp_type'-c, --command=COMMAND    run only single command (SQL or internal) and exit
## 指定数据库连接
## psql -d postgres-d, --dbname=DBNAME      database name to connect to (default: "root")
## 执行file中命令,文件中可以是SQL命令
## psql -f sql.txt-f, --file=FILENAME      execute commands from file, then exit
## 查看有效的数据库
## psql -l-l, --list               list available databases, then exit-v, --set=, --variable=NAME=VALUEset psql variable NAME to VALUE-V, --version            output version information, then exit-X, --no-psqlrc          do not read startup file (~/.psqlrc)-1 ("one"), --single-transactionexecute as a single transaction (if non-interactive)-?, --help               show this help, then exitInput and output options:-a, --echo-all           echo all input from script-e, --echo-queries       echo commands sent to server-E, --echo-hidden        display queries that internal commands generate-L, --log-file=FILENAME  send session log to file-n, --no-readline        disable enhanced command line editing (readline)-o, --output=FILENAME    send query results to file (or |pipe)-q, --quiet              run quietly (no messages, only query output)
## -s选项将你置于单步模式,该模式在将每个语句发送到服务器之前暂停-s, --single-step        single-step mode (confirm each query)-S, --single-line        single-line mode (end of line terminates SQL command)Output format options:-A, --no-align           unaligned table output mode-F, --field-separator=STRINGfield separator for unaligned output (default: "|")-H, --html               HTML table output mode-P, --pset=VAR[=ARG]     set printing option VAR to ARG (see \pset command)-R, --record-separator=STRINGrecord separator for unaligned output (default: newline)-t, --tuples-only        print rows only-T, --table-attr=TEXT    set HTML table tag attributes (e.g., width, border)-x, --expanded           turn on expanded table output-z, --field-separator-zeroset field separator for unaligned output to zero byte-0, --record-separator-zeroset record separator for unaligned output to zero byteConnection options:
## 主机名-h, --host=HOSTNAME      database server host or socket directory (default: "local socket")
## 端口-p, --port=PORT          database server port (default: "5432")
## 用户名-U, --username=USERNAME  database user name (default: "root")
## 无密码连接-w, --no-password        never prompt for password
## 设置密码连接-W, --password           force password prompt (should happen automatically)For more information, type "\?" (for internal commands) or "\help" (for SQL
commands) from within psql, or consult the psql section in the PostgreSQL
documentation.

psql

## 主机名:localhost 用户名:postgres 端口:5432 数据库:postgres 无密码登录
postgres@dd50f020b9f4:/$ psql -h localhost -U postgres -p 5432 -d postgres -w

3 ?

postgres=# \?
General
## 发行版本\copyright             show PostgreSQL usage and distribution terms\g [FILE] or ;         execute query (and send results to file or |pipe)\gset [PREFIX]         execute query and store results in psql variables\h [NAME]              help on syntax of SQL commands, * for all commands
## 退出\q                     quit psql\watch [SEC]           execute query every SEC secondsQuery Buffer\e [FILE] [LINE]       edit the query buffer (or file) with external editor\ef [FUNCNAME [LINE]]  edit function definition with external editor\p                     show the contents of the query buffer\r                     reset (clear) the query buffer\s [FILE]              display history or save it to file\w FILE                write query buffer to fileInput/Output\copy ...              perform SQL COPY with data stream to the client host\echo [STRING]         write string to standard output
## 读取文件SQL指令,并执行\i FILE                execute commands from file\ir FILE               as \i, but relative to location of current script\o [FILE]              send all query results to file or |pipe\qecho [STRING]        write string to query output stream (see \o)Informational(options: S = show system objects, + = additional detail)
## 查看表、视图、序列\d[S+]                 list tables, views, and sequences
## 相当于MySQL的desc table\d[S+]  NAME           describe table, view, sequence, or index\da[S]  [PATTERN]      list aggregates\db[+]  [PATTERN]      list tablespaces\dc[S+] [PATTERN]      list conversions\dC[+]  [PATTERN]      list casts\dd[S]  [PATTERN]      show object descriptions not displayed elsewhere\ddp    [PATTERN]      list default privileges\dD[S+] [PATTERN]      list domains\det[+] [PATTERN]      list foreign tables\des[+] [PATTERN]      list foreign servers\deu[+] [PATTERN]      list user mappings\dew[+] [PATTERN]      list foreign-data wrappers\df[antw][S+] [PATRN]  list [only agg/normal/trigger/window] functions\dF[+]  [PATTERN]      list text search configurations\dFd[+] [PATTERN]      list text search dictionaries\dFp[+] [PATTERN]      list text search parsers\dFt[+] [PATTERN]      list text search templates
## 查看用户及权限\dg[+]  [PATTERN]      list roles\di[S+] [PATTERN]      list indexes\dl                    list large objects, same as \lo_list\dL[S+] [PATTERN]      list procedural languages\dm[S+] [PATTERN]      list materialized views
## 查看schema\dn[S+] [PATTERN]      list schemas\do[S]  [PATTERN]      list operators\dO[S+] [PATTERN]      list collations\dp     [PATTERN]      list table, view, and sequence access privileges\drds [PATRN1 [PATRN2]] list per-database role settings\ds[S+] [PATTERN]      list sequences
## 查看table\dt[S+] [PATTERN]      list tables\dT[S+] [PATTERN]      list data types\du[+]  [PATTERN]      list roles
## 查看视图\dv[S+] [PATTERN]      list views\dE[S+] [PATTERN]      list foreign tables\dx[+]  [PATTERN]      list extensions\dy     [PATTERN]      list event triggers
## 查看所有数据库  \l[+]   [PATTERN]      list databases\sf[+] FUNCNAME        show a function's definition\z      [PATTERN]      same as \dpFormatting\a                     toggle between unaligned and aligned output mode\C [STRING]            set table title, or unset if none\f [STRING]            show or set field separator for unaligned query output\H                     toggle HTML output mode (currently off)\pset [NAME [VALUE]]   set table output option(NAME := {border|columns|expanded|fieldsep|fieldsep_zero|footer|format|linestyle|null|numericlocale|pager|recordsep|recordsep_zero|tableattr|title|tuples_only})\t [on|off]            show only rows (currently off)\T [STRING]            set HTML <table> tag attributes, or unset if none\x [on|off|auto]       toggle expanded output (currently off)Connection
## 连接到其他数据库\c[onnect] {[DBNAME|- USER|- HOST|- PORT|-] | conninfo}connect to new database (currently "postgres")
## 查看编码         \encoding [ENCODING]   show or set client encoding
## 修改密码  \password [USERNAME]   securely change the password for a user
## 查看连接信息  \conninfo              display information about current connectionOperating System\cd [DIR]              change the current working directory\setenv NAME [VALUE]   set or unset environment variable\timing [on|off]       toggle timing of commands (currently off)\! [COMMAND]           execute command in shell or start interactive shellVariables\prompt [TEXT] NAME    prompt user to set internal variable\set [NAME [VALUE]]    set internal variable, or list all if no parameters\unset NAME            unset (delete) internal variableLarge Objects\lo_export LOBOID FILE\lo_import FILE [COMMENT]\lo_list\lo_unlink LOBOID      large object operations

4 role用户

## 查看所有role
postgres=# \dgList of rolesRole name |                   Attributes                   | Member of
-----------+------------------------------------------------+-----------postgres  | Superuser, Create role, Create DB, Replication | {}zxy       | Create DB                                      | {}## 创建role:dba
postgres=# create role dba login password 'dba';
CREATE ROLE
## 检查dba创建情况
postgres=# \dgList of rolesRole name |                   Attributes                   | Member of
-----------+------------------------------------------------+-----------dba       |                                                | {}postgres  | Superuser, Create role, Create DB, Replication | {}zxy       | Create DB                                      | {}
## 为dba分配超级管理员权限
postgres=# alter user dba Superuser;
ALTER ROLE
postgres=# \dgList of rolesRole name |                   Attributes                   | Member of
-----------+------------------------------------------------+-----------dba       | Superuser                                      | {}postgres  | Superuser, Create role, Create DB, Replication | {}zxy       | Create DB                                      | {}postgres=#

5 point特殊字段类型

postgres=# create table map (province text null,position point null
);postgres=# insert into map values ('**市','121.48,31.22');postgres=# select * from map;province |    position
----------+----------------**市     | (121.48,31.22)
(1 row)

6 copy

## 主机创建map.txt文件,随机模拟数据
[root@zxy_master docker]# cat map.txt
上海市  1111,11
江苏省  2222,22
浙江省  3333,33
河南省  4444,44## 主机发送到docker容器中
## 将主机的/zxy/apps/docker/map.txt
## 发送到容器的/data/postgres/file
[root@zxy_master docker]# docker cp /zxy/apps/docker/map.txt dd50f020b9f4:/data/postgres/filepostgres=# copy map from '/data/postgres/file/map.txt';
COPY 4
postgres=# select * from map ;province |    position
----------+----------------**市     | (121.48,31.22)上海市   | (1111,11)江苏省   | (2222,22)浙江省   | (3333,33)河南省   | (4444,44)
(5 rows)

7 create

table

create table zxy (
a bigint null,
b text null,
);

view

create view asselect a,bfrom zxy

Foreign Keys

## 创建cities表,主键name
postgres=# create table ods.cities (
postgres(# name text primary key,
postgres(# location point );
CREATE TABLE## 创建weather,外键cities的name字段
postgres=# create table weather (
postgres(# city text references cities(name),
postgres(# temp int,
postgres(# date date );
CREATE TABLE## 模拟数据插入cities
postgres=# insert into ods.cities values('shanghai','1111,1111');
INSERT 0 1## 模拟数据插入weather,其中city已经在cities中存在
postgres=# insert into ods.weather values('shanghai',45,'2022-04-19');
INSERT 0 1
## cities数据插入成功
postgres=# select * from ods.cities;name   |  location
----------+-------------shanghai | (1111,1111)
(1 row)## weather数据插入成功
postgres=# select * from ods.weather;city   | temp |    date
----------+------+------------shanghai |   45 | 2022-04-19
(1 row)## 如果插入一个cities中不存在的name:jiangsu,那么就插入失败
postgres=# insert into ods.weather values('jiangsu',45,'2022-04-19');
ERROR:  insert or update on table "weather" violates foreign key constraint "weather_city_fkey"
DETAIL:  Key (city)=(jiangsu) is not present in table "cities".
postgres=#

function

postgres=# create or replace function ods.p_city()
postgres-# returns void
postgres-# LANGUAGE plpgsql
postgres-# as $function$
postgres$# BEGIN
postgres$# insert into ods.weather(city) select name from ods.cities;
postgres$# end;
postgres$# $function$
postgres-# ;
CREATE FUNCTION
postgres=#

8 事务

## 1.模拟数据
## 1.1创建表包括名字和账户额
postgres=# create table ods.account(
postgres(# name text null,
postgres(# account bigint null );
CREATE TABLE
## 1.2模拟插入三条数据
postgres=# insert into ods.account values('alice',200),('bob',100),('tom',300);
INSERT 0 3
## 1.3查看
postgres=# select * from ods.account;name  | account
-------+---------alice |     200bob   |     100tom   |     300
(3 rows)## 2.测试事务
## 将alice的100元转给bob,但是突然发现是需要转给tom
## 设置 savepoint,通过rollback返回point点
## 重新将100元转给tom
postgres=# begin;
BEGIN
postgres=# update ods.account set account = account - 100 where name = 'alice';
UPDATE 1
postgres=# savepoint my_savepoint;
SAVEPOINT
postgres=# update ods.account set account = account + 100 where name = 'bob'
postgres-# ;
UPDATE 1
postgres=# rollback to my_savepoint;
ROLLBACK
postgres=# update ods.account set account = account + 100 where name = 'tom';
UPDATE 1
postgres=# commit;
COMMIT
postgres=# select * from ods.account ;name  | account
-------+---------bob   |     100alice |     100tom   |     400
(3 rows)

9 over

9.1 模拟数据

## 建表
postgres=# create table ods.number(id int null,name text null,number decimal(10,2) null);
CREATE TABLE
## 模拟数据
postgres=# insert into ods.number values(1,'a',100),(2,'b',100),(3,'c',400),(4,'d',300),(5,'e',300);
INSERT 0 5
## 查看数据
postgres=# select * from ods.number;id | name | number
----+------+--------1 | a    | 100.002 | b    | 100.003 | c    | 400.004 | d    | 300.005 | e    | 300.00
(5 rows)

9.2 排名函数

## 不中断,不重复
postgres=# select id ,name ,number ,row_number() over( order by number desc) from ods.number;id | name | number | row_number
----+------+--------+------------3 | c    | 400.00 |          14 | d    | 300.00 |          25 | e    | 300.00 |          31 | a    | 100.00 |          42 | b    | 100.00 |          5
(5 rows)## 不中断,重复
postgres=# select id ,name ,number ,dense_rank() over( order by number desc) from ods.number;id | name | number | dense_rank
----+------+--------+------------3 | c    | 400.00 |          14 | d    | 300.00 |          25 | e    | 300.00 |          21 | a    | 100.00 |          32 | b    | 100.00 |          3
(5 rows)## 中断,重复
postgres=# select id ,name ,number ,rank() over( order by number desc) from ods.number;id | name | number | rank
----+------+--------+------3 | c    | 400.00 |    14 | d    | 300.00 |    25 | e    | 300.00 |    21 | a    | 100.00 |    42 | b    | 100.00 |    4
(5 rows)

9.3 聚合函数

## sum() over()
postgres=# select id,name,number,number/sum(number) over() from ods.number;id | name | number |        ?column?
----+------+--------+------------------------1 | a    | 100.00 | 0.083333333333333333332 | b    | 100.00 | 0.083333333333333333333 | c    | 400.00 | 0.333333333333333333334 | d    | 300.00 | 0.250000000000000000005 | e    | 300.00 | 0.25000000000000000000
(5 rows)

9.4 平均值

## avg() over()
postgres=# select id,name,number,avg(number) over() from ods.number;id | name | number |         avg
----+------+--------+----------------------1 | a    | 100.00 | 240.00000000000000002 | b    | 100.00 | 240.00000000000000003 | c    | 400.00 | 240.00000000000000004 | d    | 300.00 | 240.00000000000000005 | e    | 300.00 | 240.0000000000000000

10 继承-Inheritance

## 1.查看map表
postgres=# \d ods.mapTable "ods.map"Column  | Type  | Modifiers
----------+-------+-----------province | text  |position | point |## 2.创建表capitals继承ods.map的province和position字段
postgres=# create table ods.capitals ( state text unique not null ) inherits(ods.map);
CREATE TABLE## 3.查看ods.capitals字段
postgres=# \d ods.capitalsTable "ods.capitals"Column  | Type  | Modifiers
----------+-------+-----------province | text  |position | point |state    | text  | not null
Indexes:"capitals_state_key" UNIQUE CONSTRAINT, btree (state)
Inherits: map## 4.查看表数据
postgres=# select * from ods.capitals;province | position | state
----------+----------+-------
(0 rows)

11 常数

字符串常量

## 换行符连接字符串
postgres=# select 'z'
postgres-# 'x'
postgres-# 'y'
postgres-# ;?column?
----------zxy
(1 row)## '||'连接字符串
postgres=# select 'z'||'x'||'y';?column?
----------zxy
(1 row)

转移字符

反斜杠转义字符 解释
\b 退格
\f 换页
\n 换行
\r 回车
\t tab
\o 八进制字节值
\xh 十六进制字节值
\uxxxx 16或32位十六进制Unicode字符值

\t - tab

## 不生效
postgres=# select 'x' || '\t' || 'x';?column?
----------x\tx
(1 row)
## 不生效
postgres=# select 'x' || '\\t' || 'x';?column?
----------x\\tx
(1 row)
## 生效
postgres=# select 'x' || E'\t' || 'x';?column?
-----------x       x
(1 row)postgres=#

举例

## string_to_array('待分割字符','分隔符')
postgres=# select string_to_array('https://www.douban.com/gallery/topic/305785','/') as strings;strings
-------------------------------------------------{https:,"",www.douban.com,gallery,topic,305785}
(1 row)
## regexp_split_to_array('待分割字符',E'正则表达式')
postgres=# select regexp_split_to_array('https://www.douban.com/gallery/topic/305785',E'\\/') as strings
postgres-# ;strings
-------------------------------------------------{https:,"",www.douban.com,gallery,topic,305785}
(1 row)

12 强转类型

## 方式一
postgres=# select '3.14159'::decimal(10,2);numeric
---------3.14
(1 row)## 方式二
postgres=# select decimal(10,2) '3.14159';numeric
---------3.14
(1 row)## 方式三
postgres=# select cast('3.14159' as decimal(10,2));numeric
---------3.14
(1 row)

13 特殊符号

  • $符号后跟数据的美元符号()用于表示函数定义体或预准备语句中的位置参数
  • ()括号具有通常的含义,用于强制执行优先级
  • []方括号用于选择数组的元素
  • ,逗号在某些结构中用于分割列表的元素
  • ;分号中止SQL命令
  • :冒号用于从数据中切片
  • *星号在某些上下文用于表示表行或复合值的所有字段
  • .句点用于数字常量,用于分割模式、表和列名

14 注释

-- SQL注释
/*
* 多行注释
*/

15 位置参数

## 适用$1获取,ods.p_map()传入的第一个参数
postgres=# create or replace function ods.p_map(text)
postgres-# returns ods.map
postgres-# LANGUAGE sql
postgres-# as $FUNCTION$
postgres$# select * from ods.map where province = $1;
postgres$# $FUNCTION$
postgres-# ;
CREATE FUNCTION
postgres=# select ods.p_map('上海市');p_map
----------------------(上海市,"(1111,11)")
(1 row)

16 数组下标

## 先适用string_to_array将字符串通过.划分为数组
## 根据下标依次获取数组中元素
postgres=# select str[1],str[2],str[3]
postgres-# from (
postgres(# select string_to_array('http://www.baidu.com','.') str
postgres(# ) t
postgres-# ;str     |  str  | str
------------+-------+-----http://www | baidu | com
(1 row)

17 聚合表达式

string_agg()


postgres=# select province,string_agg(province || position ,E'\n') over(partition by province order by province desc) from ods.map;province |   string_agg
----------+-----------------浙江省   | 浙江省(3333,33)河南省   | 河南省(4444,44)江苏省   | 江苏省(2222,22)+| 江苏省(232,323)江苏省   | 江苏省(2222,22)+| 江苏省(232,323)上海市   | 上海市(1111,11)+| 上海市(121,211)上海市   | 上海市(1111,11)+| 上海市(121,211)
(6 rows)

array_agg()


postgres=# select province,array_agg(province || position) over(partition by province order by province desc) from ods.map;province |               array_agg
----------+---------------------------------------浙江省   | {"浙江省(3333,33)"}河南省   | {"河南省(4444,44)"}江苏省   | {"江苏省(2222,22)","江苏省(232,323)"}江苏省   | {"江苏省(2222,22)","江苏省(232,323)"}上海市   | {"上海市(1111,11)","上海市(121,211)"}上海市   | {"上海市(1111,11)","上海市(121,211)"}
(6 rows)postgres=#

18 filter

## generate_series(x,y,n)
## x为起始点,y为结束点,n为移动步长
## filter () 可直接添加条件做筛选
postgres=# select count(*) as unfiltered,
postgres-# count(*) filter (where i < 5) as filtered
postgres-# from generate_series(1,10) as s(i);unfiltered | filtered
------------+----------10 |        4
(1 row)

19 COLLATE排序规则表达式

## 设置text的排序规则表达式为C
postgres=# create table ods.collating(id bigint null,num text collate "C" null);
CREATE TABLE
postgres=# \d ods.collatingTable "ods.collating"Column |  Type  | Modifiers
--------+--------+-----------id     | bigint |num    | text   | collate Cpostgres=# select id,num collate "C" from ods.collating order by collating;id | num
----+-----1 | zxy
(1 row)

20 array

## 1.array数组
postgres=# select array[1,2,3];array
---------{1,2,3}
(1 row)
## 2.转换类型
postgres=# select array[province,position]::text[] from ods.map;array
----------------------{上海市,"(1111,11)"}{江苏省,"(2222,22)"}{浙江省,"(3333,33)"}{河南省,"(4444,44)"}{上海市,"(121,211)"}{江苏省,"(232,323)"}
(6 rows)
## 3.数组里面包数组
postgres=# select array[array[province,position],array[position,province]]::text[] from ods.map;array
---------------------------------------------{{上海市,"(1111,11)"},{"(1111,11)",上海市}}{{江苏省,"(2222,22)"},{"(2222,22)",江苏省}}{{浙江省,"(3333,33)"},{"(3333,33)",浙江省}}{{河南省,"(4444,44)"},{"(4444,44)",河南省}}{{上海市,"(121,211)"},{"(121,211)",上海市}}{{江苏省,"(232,323)"},{"(232,323)",江苏省}}
(6 rows)
## 4.1 创建含有数组字段的表
postgres=# create table ods.arr(id int null,f1 text[] null);
CREATE TABLE
## 4.2 向表中插入数据
postgres=# insert into ods.arr(id,f1) select 1,array[array[province,position],array[position,province]]::text[] from ods.map;
INSERT 0 6
## 4.3查看表数据
postgres=# select * from ods.arr;id |                     f1
----+---------------------------------------------1 | {{上海市,"(1111,11)"},{"(1111,11)",上海市}}1 | {{江苏省,"(2222,22)"},{"(2222,22)",江苏省}}1 | {{浙江省,"(3333,33)"},{"(3333,33)",浙江省}}1 | {{河南省,"(4444,44)"},{"(4444,44)",河南省}}1 | {{上海市,"(121,211)"},{"(121,211)",上海市}}1 | {{江苏省,"(232,323)"},{"(232,323)",江苏省}}
(6 rows)

21 functions

1. 调用函数-位置符号

## 1.测试案例:创建一个函数,传入小写字母返回大写字母,传入大写字母返回小写字母
postgres=# create function ods.p_concat_lower_or_upper(a text,b text,uppercase boolean default false)
postgres-# returns text
postgres-# as
postgres-# $$
postgres$# select case
postgres$# when $3 then upper($1 || '-' || $2)
postgres$# else lower($1 || '-' || $2)
postgres$# end;
postgres$# $$
postgres-# language sql
postgres-# immutable strict;
CREATE FUNCTION## 2.1位置符号--传值,支持函数
postgres=# select ods.p_concat_lower_or_upper('a','b',true);p_concat_lower_or_upper
-------------------------A-B
(1 row)## 2.2位置符号-默认参数,可省略
postgres=# select ods.p_concat_lower_or_upper('A','B');p_concat_lower_or_upper
-------------------------a-b
(1 row)## 3命名符号
postgres=# select ods.p_concat_lower_or_upper(a:='HELLO',b:='WORLD');p_concat_lower_or_upper
-------------------------hello-world
(1 row)## 4.混合符号
postgres=# select ods.p_concat_lower_or_upper('hello','world',uppercase:=true);p_concat_lower_or_upper
-------------------------HELLO-WORLD
(1 row)

22 constraints

检查约束

## 1.创建表constraints,并为price设置约束条件
## 适用constraint为该约束自定义命名
## 若不自定义命名,则系统会随机分配
postgres=# create table ods.constraints(product_no text null,name text null,price numeric constraint positive_price check (price > 0));
CREATE TABLE
## 2.price > 0 ,符合约束条件
postgres=# insert into ods.constraints values('xxx','xxx',120);
INSERT 0 1
## 3.price < 0 , 不符合约束条件
postgres=# insert into ods.constraints values('xxx','xxx',-1);
ERROR:  new row for relation "constraints" violates check constraint "positive_price"
DETAIL:  Failing row contains (xxx, xxx, -1).

非空约束

## 1.创建具有非空约束字段produce_no,price
postgres=# create table ods.constraints2(
postgres(# product_no text not null,
postgres(# name text null,
postgres(# price numeric not null constraint positive_price check(price > 0));
CREATE TABLE
## 2.如product_no为null,则插入数据失败
postgres=# insert into ods.constraints2(name,price) values('zxy',120);
ERROR:  null value in column "product_no" violates not-null constraint
DETAIL:  Failing row contains (null, zxy, 120).
## 3.符合非空约束
postgres=# insert into ods.constraints2(product_no,name,price) values('xxx','zxy',120);
INSERT 0 1
postgres=# select * from ods.constraints2;product_no | name | price
------------+------+-------xxx        | zxy  |   120
(1 row)postgres=#

唯一性约束

## 1.创建唯一性约束条件(a,b)
postgres=# create table ods.constraints3(
postgres(# a integer null,
postgres(# b integer null,
postgres(# c integer null,
postgres(# unique (a,b));
CREATE TABLE
## 2.这里插入数据后,(1,2)就作为了唯一性条件
postgres=# insert into ods.constraints3 values(1,2,3);
INSERT 0 1
## 3.再次插入有(1,2)的数据后,不符合唯一性条件,插入失败
postgres=# insert into ods.constraints3 values(1,2,4);
ERROR:  duplicate key value violates unique constraint "constraints3_a_b_key"
DETAIL:  Key (a, b)=(1, 2) already exists.
postgres=#

主键

postgres=# create table ods.constraints4(
postgres(# a integer,
postgres(# b integer,
postgres(# c integer,
postgres(# primary key (a,b));
CREATE TABLEpostgres=# insert into ods.constraints4 values(1,2,3);
INSERT 0 1postgres=# insert into ods.constraints4 values(1,2,4);
ERROR:  duplicate key value violates unique constraint "constraints4_pkey"
DETAIL:  Key (a, b)=(1, 2) already exists.
postgres=#

外键

## 外键(d,e)对应ods.constraints3表的主键(a,b)
postgres=# create table ods.constraints5(
postgres(# d integer,
postgres(# e integer,
postgres(# f integer,
postgres(# foreign key (d,e) references ods.constraints3(a,b));
CREATE TABLE

23 alter

alter table ods.table rename to ods.table2

1. Column

## 添加字段
alter table ods.table add column description text check (description <> '');
## 删除字段
alter table ods.table drop colum description;
## 级联删除
alter table ods.table drop column description cascade;
## 修改字段类型
alter table ods.table alter column description type numeric(10,2)
## 重命名列
alter table ods.table rename column description to desc;

2. constraint

## 添加约束
alter table ods.table add constraint check_name check(name <> '');
alter table ods.table add foreign key (name) references ods.table2;
## 删除约束
alter table ods.table drop constraint check_name check(name <> '');
alter table ods.table alter column description drop not null;

3.default

alter table ods.table alter column price set default 7.77;
alter table ods.table alter column price drop default;

24 privileges

## 为zxy授予ods.table的select查询权限
grant select on ods.table to zxy;
grant select on schema to zxy;
## 收回zxy对ods.table的所有权限
revoke all on ods.table from zxy;
revoke all on schema from zxy;
privilege Abbreviation Applicable Object Types
SELECT r(read) LARGE OBJECT,SQUENECE,TABLE,TABLE COLUMN
INSERT a(append) TABLE,TABLE COLUMN
UPDATE w(write) LARGE OBJECT,SEQUENCE,TABLE,TABLE COLUMN
DELETE d TABLE
TRUNCATE D TABLE
REFERENCES x TABLE,TABLE COLUMN
TRIGGER t TABLE
CREATE C DATABASE,SCHEMA,TABLESPACE
CONNECT c DATABASE
TEMPORARY T DATABASE
EXECUTE X FUNCTION,PROCEDURE
USAGE U DOMAIN,FOREIGN DATA WRAPPER,FOREIGN SEVER,LANGUAGE,SCHEMA,SEQUENCE,TYPE

举例:

## 1.查看ods.map的表权限
postgres=# \dp ods.map;Access privilegesSchema | Name | Type  |     Access privileges     | Column access privileges
--------+------+-------+---------------------------+--------------------------ods    | map  | table | postgres=arwdDxt/postgres |
(1 row)## 2.为ods.map分配select\update\delete权限
postgres=# grant select,update,delete on ods.map to zxy;
GRANT## 3.查看ods.map的权限
postgres=# \dp ods.map;Access privilegesSchema | Name | Type  |     Access privileges     | Column access privileges
--------+------+-------+---------------------------+--------------------------ods    | map  | table | postgres=arwdDxt/postgres+||      |       | zxy=rwd/postgres          |
(1 row)

15 policy

行安全策略policy,这些策略基于每个用户来限制正常查询可以返回哪些行,或者可以通过数据修改命令插入、更新或者删除哪些行。此功能也称为行级安全性。默认情况下,表没有任何策略,因此如果用户根据SQL权限对表具有访问权限,则表中的所有行都可以同等的用于查询或更新

16 schema

数据库->模式->表

1.使用模式的几个原因:

  • 允许多个用户适用一个数据库而不受影响
  • 将数据库对象组织成逻辑组以使其更易管理
  • 第三方应用程序可以放入单独的模式中,这样他们就不会与其他对象的名称发生冲突

模式类似于操作系统级别的目录,只是模式不能嵌套。

2.查询

## 查看所有数据库
postgres=# \lList of databasesName    |  Owner   | Encoding |  Collate   |   Ctype    |   Access privileges
-----------+----------+----------+------------+------------+-----------------------postgres  | postgres | UTF8     | en_US.utf8 | en_US.utf8 |template0 | postgres | UTF8     | en_US.utf8 | en_US.utf8 | =c/postgres          +|          |          |            |            | postgres=CTc/postgrestemplate1 | postgres | UTF8     | en_US.utf8 | en_US.utf8 | =c/postgres          +|          |          |            |            | postgres=CTc/postgres
(3 rows)## 查看schema
postgres=# \dnList of schemasName  |  Owner
--------+----------ads    | postgresdwd    | postgresdws    | postgresods    | postgrespublic | postgreszxy    | postgres## 查看数据库.模式.表名
## database.schema.table
postgres=# select * from postgres.ods.map;province | position
----------+-----------上海市   | (1111,11)江苏省   | (2222,22)浙江省   | (3333,33)河南省   | (4444,44)上海市   | (121,211)江苏省   | (232,323)
(6 rows)## 查看模式.表名
## schema.table
postgres=# select * from ods.map;province | position
----------+-----------上海市   | (1111,11)江苏省   | (2222,22)浙江省   | (3333,33)河南省   | (4444,44)上海市   | (121,211)江苏省   | (232,323)
(6 rows)

3.操作模式

create schema myschema;
create schema myschema authorization user_name;
drop schema myschema;
drop schema myschema cascade;

4.公共模式

创建表的时候不指定任何模式。默认情况下,此类表会被自动放到名为public的模式中

## 1.设置模式搜索路径:search_path=public
postgres=# set search_path=public;
SET
## 2.创建表不指定schema
postgres=# create table text(id int null,name text null);
CREATE TABLE
## 3.查看public下的表是否有text
postgres=# \dtList of relationsSchema |            Name            | Type  |  Owner
--------+----------------------------+-------+----------public | auth_group                 | table | postgrespublic | auth_group_permissions     | table | postgrespublic | auth_permission            | table | postgrespublic | auth_user                  | table | postgrespublic | auth_user_groups           | table | postgrespublic | auth_user_user_permissions | table | postgrespublic | django_admin_log           | table | postgrespublic | django_content_type        | table | postgrespublic | django_migrations          | table | postgrespublic | django_session             | table | postgrespublic | text                       | table | postgres
(11 rows)

17 分区

1.概述

分区是指将逻辑是一张大表拆分为较小的物理块。分区可以提供几个好处:

  • 在某些情况下,查询性能可以显著提高,尤其是当表的大部分访问量很大的行位于单个分区或少数几个分区中时,分区有效的替代了较高的树级别索引,使得索引的大量使用部分更有可能适合内存
  • 当查询或更新访问单个分区的很大部分时,可以通过使用该分区的顺序扫描而不是使用索引来提高性能,这需要分散在整个表中的随机访问读取
  • 如果在分区设计中考虑了使用模式,则可以通过添加或删除分区来完成批量的加载和删除。drop table使用或做删除单个分区alter tale detach partition 比批量操作要快。这些命令也完全避免了vacuum一个bulk带来的开销delete
  • 很少使用的数据可以迁移到更便宜、更慢的介质上

这些好处通常只有在非常大时才值得。表从分区中收益的确切点取决于应用程序,但经验法则是表的大小应该超过数据库服务器的物理内存。

PostGreSQL为以下分区形式提供内置支持:

  • 范围分区

    该表被划分为由键列或列集定义的“范围”,分配给不同分区的值范围之间没有重叠。例如,可以按日期范围或特定业务对象的标识符范围进行分区。每个范围的界限被理解为在下端包含在内,在上端不包含在内。例如,如果一个分区的范围是from 1 to 10,而下一个分区的范围是from 10 to 20,那么value10属于第二分区,而不是第一个

  • 列表分区

    通过显式列出每个分区中出现的键值对表进行分区

  • 哈希分区

    通过为每个分区指定模数和余数来对表进行分区。每个分区将保存分区键的哈希值除以指定模数将产生指定余数的行

如果应用程序需要使用上面未列出的其他形式的分区,UNION ALL则可以使用继承和视图等替代方法。这些方法提供了灵活性,但是没有内置声明性分区的一些性能优势。

2.创建分区并测试

Postgres支持通过表继承进行分区。每个分区必须做单独一个父表的子表进行创建。父表自身通常是空的,他的存在只是未了代表整个数据集,简单的说,Postgres通过表继承的方式实现分区

2.1 创建父表

## 创建ods.part表,包括id,名称,销售,创建时间等字段
postgres=# create table ods.part (
postgres(# id int not null,
postgres(# name text not null,
postgres(# sale decimal(10,2) not null,
postgres(# create_time date not null );
CREATE TABLE
postgres=# \d ods.partTable "ods.part"Column    |     Type      | Modifiers
-------------+---------------+-----------id          | integer       | not nullname        | text          | not nullsale        | numeric(10,2) | not nullcreate_time | date          | not null

2.2 创建子表

每个子表相当于一个分区

## 按照时间上的分区,3月份
postgres=# create table ods.part_y202203 (
postgres(# check (create_time >= date '2022-03-01' and create_time <= '2022-03-31')
postgres(# ) inherits(ods.part);
CREATE TABLE
## 按照时间上的分区,4月份
postgres=# create table ods.part_y202204 (
check (create_time >= date '2022-04-01' and create_time <= '2022-04-30')
) inherits(ods.part);
CREATE TABLE

2.3 创建存储过程

CREATE OR REPLACE FUNCTION ods.p_function_insert_part()
RETURNS TRIGGER AS $$
BEGINIF (NEW.create_time >= date '2022-03-01' and NEW.create_time <= '2022-03-31') THENINSERT INTO ods.part_y202203 VALUES(NEW.*);ELSIF (NEW.create_time >= date '2022-04-01' and NEW.create_time <= '2022-04-30') THENINSERT INTO ods.part_y202204 VALUES(NEW.*);ELSE RAISE EXCEPTION 'error';END IF;RETURN NULL;
end;
$$
LANGUAGE plpgsql ;

2.4 为父表创建触发器

create trigger t_trigger_insert_part
before insert on ods.part
for each row execute
procedure ods.p_function_insert_part();

2.5 插入数据测试

## 1.分别插入3月和4月的一条数据
postgres=# insert into ods.part values(1,'sale1',119.998,'2022-03-04'),(2,'sale2',82.231,'2022-04-21');
INSERT 0 0
## 2.主表中存在两条数据
postgres=# select * from ods.part;id | name  |  sale  | create_time
----+-------+--------+-------------1 | sale1 | 120.00 | 2022-03-042 | sale2 |  82.23 | 2022-04-21
(2 rows)
## 3.3月份的分区表只有三月份日期的数据
postgres=# select * from ods.part_y202203;id | name  |  sale  | create_time
----+-------+--------+-------------1 | sale1 | 120.00 | 2022-03-04
(1 row)
## 4.4月份的分区表只有四月份日期的数据
postgres=# select * from ods.part_y202204;id | name  | sale  | create_time
----+-------+-------+-------------2 | sale2 | 82.23 | 2022-04-21
(1 row)postgres=#

18 returning

## 1.删除数据使用returning查看已删除行的内容
postgres=# delete from ods.part where create_time = '2022-03-05' returning *;id | name  |  sale  | create_time
----+-------+--------+-------------2 | sale1 | 120.00 | 2022-03-05
(1 row)## 2.修改数据使用returning返回新的数据行
postgres=# update ods.part set create_time = '2022-03-31' where create_time = '2022-03-05' returning *;id | name  |  sale  | create_time
----+-------+--------+-------------2 | sale1 | 120.00 | 2022-03-31
(1 row)

目前看到第七章

19 join

  • inner join

    对于T1的每一行R1,连接表对于T2中满足与R1的连接条件的每一行都有一行

  • left outer join

    首先,执行内连接。然后,对于T1中与T2中的任何行不满足连接条件的每一行,在T2的列中添加一个带有空值的连接行,因此,连接表对于T1中的每一个行总是至少有一行

  • right outer join

    首先,执行内连接。然后,对于T2中与T1中的任何行不满足连接条件的每一行,在T2的列中添加一个带有空值的连接行。这与左连接恰恰相反:结果表始终为T2的每一行保留一行。

  • full outer join

    首先,执行内连接。然后,对于T1中与T2中任何不满足连接条件的每一行,在T 2 的列中添加一个带有空值的连接行。此外,对于T2中与T1中的任何行不满足连接条件的每一行,添加一个在T1的列中具有空值的连接行。

20 grouping sets / rollup / cube

基本使用

rollup(e1,e2,e3)
=>
grouping sets ((e1,e2,e3),(e1,e2),(e1),())cube(e1,e2,e3)
=>
grouping sets ((e1,e2,e3),(e1,e2),(e1,e3),(e1),(e2,e3),(e2),(e3),())

复杂使用

group by a,cube(b,c),grouping sets ((d),(e))
=>
首先cube(b,c)可以拆解为grouping sets((b,c),(b),(c))
=>
那么可以有以下几种=>
group by grouping sets ((a,b,c,d),(a,b,c,e),(a,b,d),(a,b,e),(a,d),(a,e)
)

21 union except intersect

[union] [except] [intersect] 跟 [full join] [left join] [right join]可以对比记忆

表数据


postgres=# select * from ods.number;id | name | number | sex
----+------+--------+-----1 | a    | 100.00 | 男3 | c    | 400.00 | 男5 | e    | 300.00 | 男7 | b    | 100.00 | 男2 | b    | 100.00 | 女4 | d    | 300.00 | 女6 | a    | 300.00 | 女8 | e    | 700.00 | 女9 | a    | 100.00 | 男10 | b    | 300.00 | 女
(10 rows)postgres=# select * from ods.number2;id | name | number | sex
----+------+--------+-----7 | b    | 100.00 | 男6 | a    | 300.00 | 女8 | e    | 700.00 | 女9 | a    | 100.00 | 男10 | b    | 300.00 | 女
(5 rows)

测试

## UNION去重,UNION ALL不去重
## 将number2的查询结果附加到number结果上
postgres=# select * from ods.number union select * from ods.number2;id | name | number | sex
----+------+--------+-----2 | b    | 100.00 | 女8 | e    | 700.00 | 女9 | a    | 100.00 | 男10 | b    | 300.00 | 女5 | e    | 300.00 | 男4 | d    | 300.00 | 女7 | b    | 100.00 | 男1 | a    | 100.00 | 男3 | c    | 400.00 | 男6 | a    | 300.00 | 女
(10 rows)## 返回在number查询结果存在,但是在number2查询结果不存在的数据
postgres=# select * from ods.number except select * from ods.number2;id | name | number | sex
----+------+--------+-----2 | b    | 100.00 | 女4 | d    | 300.00 | 女5 | e    | 300.00 | 男3 | c    | 400.00 | 男1 | a    | 100.00 | 男
(5 rows)## 返回在number2查询结果中存在,在number查询结果不存在的数据
postgres=# select * from ods.number intersect select * from ods.number2;id | name | number | sex
----+------+--------+-----9 | a    | 100.00 | 男10 | b    | 300.00 | 女7 | b    | 100.00 | 男6 | a    | 300.00 | 女8 | e    | 700.00 | 女
(5 rows)

22 limit/offset

## 首先使用order by 根据id升序排序
## 其次执行offset 2 从偏移量为2的地方开始统计
## 最后执行limit 5 从偏移量为2的地方往后取5行
postgres=# select * from ods.number order by 1 limit 5 offset 2;id | name | number | sex
----+------+--------+-----3 | c    | 400.00 | 男4 | d    | 300.00 | 女5 | e    | 300.00 | 男6 | a    | 300.00 | 女7 | b    | 100.00 | 男
(5 rows)

23 values

使用values可以生成 常量表,用作查询。无需实际创建和填充磁盘上的表

## 使用values指定数据内容
## 使用as 为value指定字段名
postgres=# select * from (values(1,'one'),(2,'two'),(3,'three')) as t (num ,letter);num | letter
-----+--------1 | one2 | two3 | three
(3 rows)

第八章 数据类型

24 数据类型

姓名 别名 描述
bigint int8 有符号八字节整数
bigserial serial8 自增八字节整数
bit [ (*n*) ] 定长位串
bit varying [ (*n*) ] varbit [ (*n*) ] 变长位串
boolean bool 逻辑布尔值(真/假)
box 平面上的长方形盒子
bytea 二进制数据(“字节数组”)
character [ (*n*) ] char [ (*n*) ] 定长字符串
character varying [ (*n*) ] varchar [ (*n*) ] 变长字符串
cidr IPv4 或 IPv6 网络地址
circle 在飞机上绕圈
date 日历日期(年、月、日)
double precision float8 双精度浮点数(8 字节)
inet IPv4 或 IPv6 主机地址
integer int, int4 有符号四字节整数
interval [ *fields* ] [ (*p*) ] 时间跨度
json 文本 JSON 数据
jsonb 二进制 JSON 数据,已分解
line 平面上的无限线
lseg 平面上的线段
macaddr MAC(媒体访问控制)地址
macaddr8 MAC(媒体访问控制)地址(EUI-64 格式)
money 货币金额
numeric [ (*p*, *s*) ] decimal [ (*p*, *s*) ] 可选择精度的精确数字
path 平面上的几何路径
pg_lsn PostgreSQL日志序列号
pg_snapshot 用户级事务 ID 快照
point 平面上的几何点
polygon 平面上的封闭几何路径
real float4 单精度浮点数(4 字节)
smallint int2 有符号的两字节整数
smallserial serial2 自动递增的两字节整数
serial serial4 自增四字节整数
text 变长字符串
time [ (*p*) ] [ without time zone ] 一天中的时间(无时区)
time [ (*p*) ] with time zone timetz 一天中的时间,包括时区
timestamp [ (*p*) ] [ without time zone ] 日期和时间(无时区)
timestamp [ (*p*) ] with time zone timestamptz 日期和时间,包括时区
tsquery 文本搜索查询
tsvector 文本搜索文档
txid_snapshot 用户级事务 ID 快照(已弃用;请参阅pg_snapshot
uuid 通用唯一标识符
xml XML 数据

25 货币类型

26 枚举类型

## 自定义枚举类型mood,有happy,sad,ok三个可选值
postgres=# create type mood as enum ('happy','sad','ok');
CREATE TYPE
## 创建相关表,并将current_mood设置为mood枚举类型
postgres=# create table ods.people_mood(
postgres(# id int null,
postgres(# current_mood mood null
postgres(# );
CREATE TABLE
## 插入数据,当current_date='happy'的时候,因为happy处于枚举类型mood中,插入成功
postgres=# insert into ods.people_mood values(1,'happy');
INSERT 0 1
## 插入数据,当current_date='no'的时候,因为枚举类型mood中没有no选项,插入失败
postgres=# insert into ods.people_mood values(2,'no');
ERROR:  invalid input value for enum mood: "no"
LINE 1: insert into ods.people_mood values(2,'no');^
postgres=#

27 几何类型

28 网络地址类型

29 位串类型

位串是1和0的字符串。可用于存储和可视化掩码。有两种SQL位类型,【bit(n)】\【bit varying(n)】。

bit类型数据必须与长度n完全匹配;尝试存储较短或者较长的位串都是错误的。

bit varying类型数据是可变长度的,直到最大长度n;较长的字符串将被拒接,没有指定长度的bit,将被认为等同于Bit(1)。而bit varying没有指定长度,就被认为是无限长。

## 创建bit_test表; 字段a 字段类型bit(3); 字段b 字段类型bit varying(5);
## 字段a的大小必须只有三位,不可长不可短
## 字段b的大小可以小于5位,但是不可以比5位长
postgres=# create table  ods.bit_test(
postgres(# a bit(3),
postgres(# b bit varying(5)
postgres(# );
CREATE TABLE## 查看表结构
postgres=# \d ods.bit_testTable "ods.bit_test"Column |      Type      | Modifiers
--------+----------------+-----------a      | bit(3)         |b      | bit varying(5) |## 插入字段a大小为3,符合条件
## 插入字段b大小为3,符合条件
postgres=# insert into ods.bit_test values (B'100',B'100');
INSERT 0 1## 插入字段a大小为2,不符合条件
## 插入字段b大小为3,符合条件
postgres=# insert into ods.bit_test values (B'10',B'100');
ERROR:  bit string length 2 does not match type bit(3)## 插入字段a大小为3,符合条件
## 插入字段b大小为6,不符合条件
postgres=# insert into ods.bit_test values (B'100',B'100000');
ERROR:  bit string too long for type bit varying(5)

30 全文检索-中文分词

to_tsvector to_tsquery

全文检索功能

通过跟Like做对比,测试使用to_tsvectorto_tsquery的查询效率

1. 模拟2W条数据

postgres=# create table ods.tsvector_test(id int null, name text null);
CREATE TABLE
postgres=# insert into ods.tsvector_test(id,name) select x,x||'_Zxy' from generate_series(1,20000) x ;
INSERT 0 20000

2.使用to_tsvector创建索引

postgres=# create index tsvector_test_1 on ods.tsvector_test using gin(to_tsvector('english',name));
CREATE INDEX

3.测试查询性能

select *
from ods.tsvector_test
where name like '%_Zxy';
--0.348s
select *
from ods.tsvector_test
where to_tsvector('english', name) @@ to_tsquery('english', '_Zxy')
--0.189s

中文分词

31 UUID类型

一个UUID被写成一个小写的十六进制的序列,分为几组,用连接符分割,具体是一组8位,后跟三组4位,然后是一组12位,总共32位代表128位。标准形式UUID示例如下:

a0eebc99-9c0b-4ef8-bb6d-6bb9bd380all

PostgresSQL接受以下替代形式的输入:使用大写数字,用大括号括起来的标准格式,省略部分或全部连接字符,在任何四位数字组后添加连字符;例如:

A0EEBC99-9C0B-4EF8-BB6D-6BB9BD380A11
{a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11}
a0eebc999c0b4ef8bb6d6bb9bd380a11
a0ee-bc99-9c0b-4ef8-bb6d-6bb9-bd38-0a11
{a0eebc99-9c0b4ef8-bb6d6bb9-bd380a11}

输出始终位标准格式

32 XML类型

33 json

json数据类型用于存储JSON数据,PostGreSQL提供两种存储JSON数据的类型:json和jsonb。为了对这些数据类型实现高效的查询机制,PostGreSQL还提供了jsonpath类型。

JSON/JSONB

## 区别一:
## json输入和输出的文本相同,例如baz和bar之间没有空格,输出的json也不会加上空格
postgres=# SELECT '{"bar":"baz", "balance":7.77, "active":false}'::json;json
-----------------------------------------------{"bar":"baz", "balance":7.77, "active":false}
(1 row)## jsonb不会保留语义无关的紧要细节,例如空格,这里输入的时候没有加空格,但是输出的时候jsonb会为你加上
postgres=# SELECT '{"bar":"baz", "balance":7.77, "active":false}'::jsonb;jsonb
--------------------------------------------------{"bar": "baz", "active": false, "balance": 7.77}
(1 row)## 区别二:
## jsonb种,将根据底层numeric类型的行为打印数字,实际上,这意味着使用E符合输入的数字将在没有符号的情况下打印
postgres=# SELECT '{"reading": 1.230e-5}'::json, '{"reading": 1.230e-5}'::jsonb;json          |          jsonb
-----------------------+-------------------------{"reading": 1.230e-5} | {"reading": 0.00001230}
(1 row)

JSONB Containment and Existence

## 简单的标量/原始值只包含相同的值
postgres=# SELECT '"foo"'::jsonb @> '"foo"'::jsonb;?column?
----------t
(1 row)
## 右边的数组包含在左边的数组中
postgres=# SELECT '[1, 2, 3]'::jsonb @> '[1, 3]'::jsonb;?column?
----------t
(1 row)
## 数组元素的顺序并不重要
postgres=# SELECT '[1, 2, 3]'::jsonb @> '[3, 1]'::jsonb;?column?
----------t
(1 row)
## 重复的数组元素也不重要
postgres=# SELECT '[1, 2, 3]'::jsonb @> '[1, 2, 2]'::jsonb;?column?
----------t
(1 row)
## 包含左侧单个对象
postgres=# SELECT '{"product": "PostgreSQL", "version": 9.4, "jsonb": true}'::jsonb @> '{"version": 9.4}'::jsonb;?column?
----------t
(1 row)
## 数据中,即使嵌套了一个类似的数组,也算false
postgres=# SELECT '[1, 2, [1, 3]]'::jsonb @> '[1, 3]'::jsonb;?column?
----------f
(1 row)
## 有一层嵌套,包含[[1,3]]
postgres=# SELECT '[1, 2, [1, 3]]'::jsonb @> '[[1, 3]]'::jsonb;?column?
----------t
(1 row)
## 同样,这里没有包含
postgres=# SELECT '{"foo": {"bar": "baz"}}'::jsonb @> '{"bar": "baz"}'::jsonb;?column?
----------f
(1 row)
## 包含顶级键和空对象
postgres=# SELECT '{"foo": {"bar": "baz"}}'::jsonb @> '{"foo": {}}'::jsonb;?column?
----------t
(1 row)## 数组中是否包含bar
postgres=# SELECT '["foo", "bar", "baz"]'::jsonb ? 'bar';?column?
----------t
(1 row)
## 是否包含foo元素K键
postgres=# SELECT '{"foo": "bar"}'::jsonb ? 'foo';?column?
----------t
(1 row)## 是否包含bar元素K键
postgres=# SELECT '{"foo": "bar"}'::jsonb ? 'bar';?column?
----------f
(1 row)
## 是否包含foo元素
postgres=# SELECT '"foo"'::jsonb ? 'foo';?column?
----------t
(1 row)

josn

34 Array数组

1.数组类型声明和数据存储

create table arr_table(name text,a integer[],--一维数组b integer[][],--二维数组c integer[3][3],--指定数组长度d integer array[4],e integer array--不指定数组长度
)insert into ods.arr_table(name,a,b) values('zxy','{10,20,30,40}','{{100,200},{300,400}}');
insert into ods.arr_table(name,a,b) values('zxy2',array[10,20,30,40],array[[100,200],[300,400]]);
postgres=# create table ods.arr_table(
postgres(# name text,
postgres(# a integer[],
postgres(# b integer[][],
postgres(# c integer[3][3],
postgres(# d integer array[4],
postgres(# e integer array
postgres(# );
CREATE TABLE
postgres=# insert into ods.arr_table(name,a,b) values('zxy','{10,20,30,40}','{{100,200},{300,400}}');
INSERT 0 1
postgres=# select * from ods.arr_table ;name |       a       |           b           | c | d | e
------+---------------+-----------------------+---+---+---zxy  | {10,20,30,40} | {{100,200},{300,400}} |   |   |
(1 row)postgres=# insert into ods.arr_table(name,a,b) values('zxy2',array[10,20,30,40],array[[100,200],[300,400]]);
INSERT 0 1
postgres=# select * from ods.arr_table ;name |       a       |           b           | c | d | e
------+---------------+-----------------------+---+---+---zxy  | {10,20,30,40} | {{100,200},{300,400}} |   |   |zxy2 | {10,20,30,40} | {{100,200},{300,400}} |   |   |
(2 rows)

2.查询

## 1.切片取值
postgres=# select b[1][1:2] from ods.arr_table where name = 'zxy';b
-------------{{100,200}}
(1 row)
postgres=# select b[1:2][1] from ods.arr_table where name = 'zxy';b
---------------{{100},{300}}
(1 row)## 2.检索字段b的维度
postgres=# select array_dims(b) from ods.arr_table where name = 'zxy';array_dims
------------[1:2][1:2]
(1 row)## 3.检索数组维度的上限
postgres=# select array_upper(b,1) from ods.arr_table where name = 'zxy';array_upper
-------------2
(1 row)## 4.检索数组维度的下限
postgres=# select array_lower(b,1) from ods.arr_table where name = 'zxy';array_lower
-------------1array_length
--------------2
(1 row)## 5.返回数组维度长度
postgres=# select array_length(b,1) from ods.arr_table where name = 'zxy';array_length
--------------2
(1 row)## 6.返回所有数组维度的元素
postgres=# select cardinality(b) from ods.arr_table where name = 'zxy';cardinality
-------------4
(1 row)## 7.检查b中有元素值为100的数据
postgres=# select * from ods.arr_table where 100 = any(b);name |         a         |           b           | c | d | e
------+-------------------+-----------------------+---+---+---zxy2 | {10,20,30,40}     | {{100,200},{300,400}} |   |   |zxy  | {2000,3000,60,70} | {{100,200},{300,400}} |   |   |
(2 rows)## 8.检查b中所有元素值为100的数据
postgres=# select * from ods.arr_table where 100 = all(b);name | a | b | c | d | e
------+---+---+---+---+---
(0 rows)## 9.高级查询
postgres=# SELECT f1[1][-2][3] AS e1, f1[1][-1][5] AS e2
postgres-#  FROM (SELECT '[1:1][-2:-1][3:5]={{{1,2,3},{4,5,6}}}'::int[] AS f1) AS ss;e1 | e2
----+----1 |  6
(1 row)

3.update数组

## 1.数组字段修改
## 方式一:
postgres=# update ods.arr_table set a = '{40,50,60}' where name = 'zxy';
## 方式二:
postgres=# update ods.arr_table set a = array[40,50,60,70] where name = 'zxy';## 2.数组元素修改:
## 方式一:指定下标修改
postgres=# update ods.arr_table set a[2] = 1000 where name = 'zxy';
## 方式二:指定切片修改
postgres=# update ods.arr_table set a[1:2] = Array[2000,3000] where name = 'zxy';

35 Composite Types 复合模式

1.创建复合模式

postgres=# create type  complex_user as (
postgres(# id integer,
postgres(# name text,
postgres(# sex text
postgres(# );
CREATE TYPE

2.建表使用复合模式

## 创建表,其中第一个字段detail使用自定义的复合模式complex_user
postgres=# create table ods.complex_student (
detail complex_user,
card text
);
CREATE TABLE## 插入数据的时候,通过row()插入复合模式的数据
postgres=# insert into ods.complex_student values(row(1,'zxy','man'),'student');
INSERT 0 1postgres=# select * from ods.complex_student ;detail    |  card
-------------+---------(1,zxy,man) | student
(1 row)

3.自定义函数使用复合模式

## 创建function,使用复合模式传值
postgres=# create function ods.p_student_detail(complex_user,integer) returns text
postgres-# as 'select $1.id || $1.name || $2 ' language sql;
CREATE FUNCTIONpostgres=# select ods.p_student_detail(detail,100) from ods.complex_student ;p_student_detail
------------------1zxy100
(1 row)

4.构建复合值

##以复合类型complex_user为例##方式一:单引号构造复合值
##1.正常案例:
'(1,'zxy','man')'
## 2.name字段为null,sex字段为空字符串,即不写为null,双引号表示空字符串
'(1,,"")'##方式二:ROW表达式构造复合值
ROW(1,'zxy','man')
ROW(1,null,'')

5.访问复合类型

## 查看数据
postgres=# select * from ods.complex_student ;detail    |  card
-------------+---------(1,zxy,man) | student
(1 row)## 根据SQL语法规则,不能直接使用detail.id去复合类型中的数据,会将detail识别为表名
## 所以采用括号
postgres=# select (detail).id,(detail).name,(detail).sex,card from ods.complex_student ;id | name | sex |  card
----+------+-----+---------1 | zxy  | man | student
(1 row)postgres=# select (ods.complex_student.detail).id,(ods.complex_student.detail).name,(ods.complex_student.detail).sex ,card from ods.complex_student ;id | name | sex |  card
----+------+-----+---------1 | zxy  | man | student
(1 row)

6 修改复合类型

## 1.修改前数据
postgres=# select * from ods.complex_student ;detail    |  card
-------------+---------(1,zxy,man) | student
(1 row)
## 2.update整个复合语句
postgres=# update ods.complex_student set detail = ROW(2,'zxy2','man') where (detail).id = 1;
UPDATE 1
## 3.修改后数据
postgres=# select * from ods.complex_student;detail    |  card
--------------+---------(2,zxy2,man) | student## 4.修改复合语句中单个元素
postgres=# update ods.complex_student set detail.name = 'zxy' where (detail).name = 'zxy2';
UPDATE 1## 5.修改后数据
postgres=# select * from ods.complex_student;detail    |  card
-------------+---------(2,zxy,man) | student
(1 row)

范围类型

PostGreSQL语法及高级功能(2022-06-08补充中)相关推荐

  1. 人工智能 | ShowMeAI资讯日报 #2022.06.08

    ShowMeAI日报系列全新升级!覆盖AI人工智能 工具&框架 | 项目&代码 | 博文&分享 | 数据&资源 | 研究&论文 等方向.点击查看 历史文章列表, ...

  2. 力扣(LeetCode)159. 至多包含两个不同字符的最长子串(2022.06.08)

    给定一个字符串 s ,找出 至多 包含两个不同字符的最长子串 t ,并返回该子串的长度. 示例 1: 输入: "eceba" 输出: 3 解释: t 是 "ece&quo ...

  3. [渣译文] 使用 MVC 5 的 EF6 Code First 入门 系列:为ASP.NET MVC应用程序使用高级功能...

    这是微软官方教程Getting Started with Entity Framework 6 Code First using MVC 5 系列的翻译,这里是第十二篇:为ASP.NET MVC应用程 ...

  4. Postgresql学习笔记-高级语法篇

    Postgresql学习笔记-高级语法篇 Postgresql 约束 Postgresql约束用于规定表中的数据规则. 如果存在违反约束的数据行为,行为会被约束终止. 约束可以在创建表的时候就规定(通 ...

  5. PostgreSQL语法

    PostgreSQL 语法 更多内容可以参考手册中的 SQL 语法:http://www.runoob.com/manual/PostgreSQL/sql-syntax.html. https://w ...

  6. 【跃迁之路】【488天】程序员高效学习方法论探索系列(实验阶段245-2018.06.08)...

    @(跃迁之路)专栏 实验说明 从2017.10.6起,开启这个系列,目标只有一个:探索新的学习方法,实现跃迁式成长 实验期2年(2017.10.06 - 2019.10.06) 我将以自己为实验对象. ...

  7. sql取最大值的那一行_从零学会SQL:SQL高级功能

    一.什么是窗口函数 1.什么是窗口函数? 窗口函数,也叫OLAP函数(Online Analytical Processing,联机分析处理),可以对数据库数据进行实时分析处理. 窗口函数的基本语法如 ...

  8. 利用Windows API获得系统高级功能

    利用Windows API获得系统高级功能 邹刚 VB无疑是最先进的编程工具之一,但在涉及windows 32位系统的核心编程方面--譬如一些高级功能的实现上,它仍然显得有些力不从心,这需要我们充分利 ...

  9. sql server累计求和函数_SQL基础--SQL高级功能

    一.窗口函数有什么用? 在日常工作中,经常会遇到需要在每组内排名,比如下面的业务需求: 排名问题:每个部门按业绩来排名 topN问题:找出每个部门排名前N的员工进行奖励 面对这类需求,就需要使用sql ...

最新文章

  1. 一文快速入门分库分表中间件 Sharding-JDBC (必修课)
  2. 睡前刷8分钟手机,身体兴奋1小时
  3. javascript:window.showModalDialog缓存问题
  4. TensorBay:一款易用的像Git一样数据版本管理工具!
  5. 【Shell】数某关键字在文件中出现次数
  6. LeetCode 985 Sum of Even Numbers After Queries 解题报告
  7. Spring-Bean配置-使用外部属性文件(转)
  8. 硬盘读写测试工具_买了固态硬盘不知好坏?这些测试工具帮你大忙
  9. FFmpeg总结(四)AV系列结构体之AVBuffer、AVBufferRef、AVBufferPool
  10. C 中的左值(Lvalues)和右值(Rvalues)
  11. 马哥linux视频笔记,马哥linux视频的学习笔记
  12. if (resultCode == RESULT_OK) 在红米手机上resultCode返回并不是RESULT_OK
  13. Java中Springboot实战之签到功能详解(超全面)
  14. S3C2440开发板裸机程序系列04—串口通信
  15. 题目:python 打印出如下图案(菱形):
  16. EBMIDE——延缓显示生成,优化用户响应
  17. 2021年6月大学英语六级翻译
  18. 【刚刚开源!】超级优秀地解决Python人工智能计算慢问题(附源码+长期更新+必会)
  19. mysql报ascii 0_导入mysql文件提示“ASCII '\0' appeared in the statement”
  20. Navicat 连接linux mysql 失败解决方法

热门文章

  1. 一主双从同步错误 error connecting to master ‘slave@192.168.81.158:3306‘ - retry-time: 60 retries: 1
  2. sklearn梯度提升树(GBDT)调参小结
  3. [W ParallelNative.cpp:212] Warning: Cannot set number of intraop threads after parallel work h
  4. ES5和ES6的区别。
  5. Hadoop 3.2.1 【 YARN 】源码分析 : DefaultContainerExecutor 浅析
  6. 设计测试用例的六种方法
  7. postgresql启动流程之信号初始化
  8. 罗克韦尔自动化荣膺“2019全球最具商业道德企业”,这是该公司第11年上榜
  9. 计算机组装训练知识总结,计算机组装维护实训总结
  10. 一篇就够!数据增强方法综述