likes
comments
collection
share

postgresql小结

作者站长头像
站长
· 阅读数 3

一、数据库的基本操作

(一) 对模式进行操作

1) 创建模式

如果我们想创建表的时候就是模式.表

CREATE SCHEMA myschema;

2)删除模式

  1. 删除空的schema
drop schema myschema
  1. 删除含有表的schema, 可以将下面的表格一举删除
drop schema myschema cascade

(二)对表进行操作

1) 创建表

创建表的一般格式是:

create table schema.students(
column1  类型 【约束条件】,
column2  类型 【约束条件】,
...
[约束条件]
 )

I 约束条件

i 创建约束

在 SQL 中,我们有如下约束:

  • NOT NULL - 指示某列不能存储 NULL 值。只能写在类型后面
  • UNIQUE - 保证某列的每行必须有唯一的值。可以写在类型后面 , 也可以当成函数写在column后面的约束条件中。
 create table students (
      name text,
      age int,
      unique (name)
   )

create table students1(
  name  text  unique)

如需命名 UNIQUE 约束,并定义多个列的 UNIQUE 约束,我们应当使用如下的语法, 优点是可以同时定义多个字段的约束条件, 同时命名是为了我们在删除这些约束条件的时候可以一起删除

create table students (
 id int ,
 name text,
 age int,
 studyno int,
 constraint uc_idno unique(id, name, studyno)
 );

删除的方法是:

alter table students drop constraint uc_idno;
--alter table students add constraint uc_idno unique(id, name, studyno)-- 增加约束的方法
  • PRIMARY KEY - NOT NULL 和 UNIQUE 的结合。确保某列(或两个列多个列的结合)有唯一标识,有助于更容易更快速地找到表中的一个特定的记录。使用方法同unique相似 , 一个表中的约束条件可能不只有一个。
  • FOREIGN KEY - 保证一个表中的数据匹配另一个表中的值的参照完整性。 创建方法有三种分别是:
-- 直接再类型后面添加 todo ....
  create table students (
     id int foreign key references person(id)-- 不晓得什么情况老是报错 还有待考究
     )
--  直接columns后加上
create table students (
      id int ,
      name text,
      age int,
      studyno int,
       foreign key(id) references person(pid) --  person里面的pid 必须加上unique的约束
);
--  起别名加外键
create table students (
 id int,
 constraint foreignid  foreign key(id)  references person(id))
  • CHECK - 保证列中的值符合指定的条件。 有两种使用方法
    -- 第一种是直接类型后面加上check函数 
       create students12(
     id  int check(id> 0)
     )
     -- column后面加
    create table studentsmm(
     id  int, 
     check(id > 0)
    );
    --别名 
       create table studentsmm(
     id  int, 
      constraint checkuid check(id > 0)
    );
    
    
    
  • DEFAULT - 规定没有给列赋值时的默认值。
create table test(
     id  int default 0,
      orderdate date default getdate() --使用系统值
 )
ii 修改约束
  1. 添加约束 通常有两种方法 , 一种是直接add :

     alter table students  add check (id>0)
     alter table students add foreign key(id) references person(id);
     alter table students add primary key(id);
     alter table students add unique(id)
    

    还有一种是add constraint:

     alter table table名字  add constraint 约束名   约束条件
     -- 如 :  alter table students add foreign key(id) references person(id);
    

    最后还有特殊的两种default 跟not null

     alter table students alter id set  default 1
      alter table students alter id set not null
    
  2. 修改约束: sql中想要修改约束条件一般我们使用的方法是先删除再添加, 类似 于这种

  alter TABLE test_yt.students drop constraint students_check;
ALTER TABLE test_yt.students ADD CONSTRAINT students_check CHECK (id>3)
  1. 废除约束 一般采用的是drop constraint
    alter table talename drop constraint  约束名字
    -- alter table students drop constraint students_pkey
    
    其中有两个特殊的 default not null
     alter table students alter id drop default
     alter table students alter id drop not null
    

2) 修改表

  1. 修改表名字 //注意如果是模式下面的表rename的时候 rename to 的时候不需要带上那个模式名
 alter table test_yt.students rename to student4
  1. 修改列名
    alter table test_yt.student4 rename column name to namealias
  1. 修改column的字段长度
ALTER TABLE test_yt.student4 ALTER COLUMN name   type varchar(40) 
  1. 添加column
ALTER TABLE products ADD COLUMN description text;
  1. 删除column
ALTER TABLE products DROP COLUMN description;
  1. 添加约束
ALTER TABLE products ADD CONSTRAINT 约束名 约束条件
  1. 删除约束
ALTER TABLE products DROP CONSTRAINT some_name;

3)删除表

drop table student

4) 添加表的别名

有两种写法, 一种是as alias 还有直接是在表名后面加上alias,一旦我们用了别名之后在子句中我们就不能使用原有的表名了

select * from test_yt.students1 s where s.name is null;
select * from test_yt.students1 as s where s.name is null
select * from test_yt.students1 as s where test_yt.students1.name is null  --这是错误的

(三)对表中数据增删查改

注意对表中数据进行再操作的时候是不需要加上table的 , 只有对表进行操作的时候才可以

1) 添加数据

-- 1.针对特定的column
insert into student(id,name,age) values(1,'张三',18);
-- 2. 照着 column的顺序插入数据的时候就可以不加column了, 多条数据插入的时候, 只需要后面加逗号就好了  
insert into student values(1,'zhangsan',10),(2, 'test', 12)

2) 删除数据

 delete from test_yt.student4 where name='hello'

3) 查找数据

SELECT 列名,列名
FROM 表名

4) 修改数据

update student set name='李四' where id=1

二、常用的数据类型

(一)数值类型

名字存储尺寸描述范围
smallint2字节小范围整数-32768 to +32767
integer4字节整数的典型选择-2147483648 to +2147483647
bigint8字节大范围整数-9223372036854775808 to +9223372036854775807
decimal可变用户指定精度,精确最高小数点前131072位,以及小数点后16383位
numeric可变用户指定精度,精确最高小数点前131072位,以及小数点后16383位
real4字节可变精度,不精确6位十进制精度
double precision8字节可变精度,不精确15位十进制精度
smallserial2字节自动增加的小整数1到32767
serial4字节自动增加的整数1到2147483647
bigserial8字节自动增长的大整数1到9223372036854775807

(二)日期类型

postgresql小结

(三)字符类型

名字描述
character varying(n)varchar(n)有限制的变长
character(n)char(n)定长,空格填充
text无限变长
longtext极大的文本数据
blob二进制长文本
longblob二进制极长的文本

三、常用的函数汇总

(一)数字函数

1) avg

 select avg(age) from student

2) max

 select max(age) from student

3) min

 select min(age) from student

4) sum

 select sum(age) from student

4) gratest

  select greatest (1,2,3);
  select greatest (age, id) from names;-- 选出最需大的那一列

5)latest 最小的

  select latest (1,2,3);

5)sqrt 平方根

select sqrt(25);

6)abs绝对值

select abs(-25);

7)round

select round(1.23)

8)ceil 向上取整

select ceil(1.23)

9)floor 向下取整

select floor(1.59)

10)count 返回指定列值的数目 null不计入

select count(age) from names

(二)字符串函数

1) length 相关

函数返回类型描述示例结果
length(string)intstring中字符的数目length('jose')4
bit_length(string)int字符串的位bit_length('jose')32
char_length(string) 或 character_length(string)int字符串中的字符个数char_length('jose')4

2) encode、 decode相关

函数返回类型描述示例结果
decode(string text, format text)bytea把用string表示的文本里面的二进制数据解码。 format选项和encode相同。decode('MTIzAAE=', 'base64')\x3132330001
encode(data bytea, format text)text把二进制数据编码为文本表示。支持的格式有:base64hexescapeescape 转换零字节和高位设置字节为八进制序列(```nnn`) 和双反斜杠。encode(E'123\000\001', 'base64')MTIzAAE=
md5(string)text计算string的MD5散列,以十六进制返回结果。md5('abc')900150983cd24fb0 d6963f7d28e17f72

3) 字符串连接

函数返回类型描述示例结果
concat(str "any" [, str "any" [, ...] ])text连接所有参数的文本表示。NULL 参数被忽略。concat('abcde', 2, NULL, 22)abcde222
concat_ws(sep text, str "any" [, str "any" [, ...] ])text连接所有参数,但是第一个参数是分隔符,用于将所有参数分隔。NULL 参数被忽略。concat_ws(',', 'abcde', 2, NULL, 22)abcde,2,22

4) 字符串拼接函数

函数返回类型描述示例结果
string || stringtext | 字符串连接`'Post''greSQL'`PostgreSQL
string  || non-string 或 non-string  || string  |text带有一个非字符串输入的字符串连接`'Value: '42`Value: 42

5 替换函数

函数返回类型描述示例结果
regexp_replace(string text, pattern text, replacement text [, flags text])text替换匹配 POSIX 正则表达式的子字符串。regexp_replace('Thomas', '.[mN]a.', 'M')ThM
replace(string text, from text, to text)text把字符串string里出现地所有子字符串from 替换成子字符串toreplace('abcdefabcdef', 'cd', 'XX')abXXefabXXef
overlay(string placing string from int [for int])text替换子字符串overlay('Txxxxas' placing 'hom' from 2 for 4)Thomas
replace(string text, from text, to text)text把字符串string里出现地所有子字符串from 替换成子字符串toreplace('abcdefabcdef', 'cd', 'XX')abXXefabXXef

5 字符串截取

函数返回类型描述示例结果
substring(string [from int] [for int])text截取子字符串substring('Thomas' from 2 for 3)hom
substr(string, from [, count])text抽取子字符串。和substring(string from from for count))一样substr('alphabet', 3, 2)ph

6) 大小写

函数返回类型描述示例结果
lower(string)text把字符串转化为小写lower('TOM')tom
upper(string)text把字符串转化为大写upper('tom')TOM

7) trim相关

函数返回类型描述示例结果
trim([leading|trailing| both] [characters] from string)text从字符串string的开头/结尾/两边删除只包含 characters中字符 (缺省是空白)的最长的字符串trim(both 'x' from 'xTomxx')Tom
trim([leading| trailing| both] [from] string [, characters] )texttrim()的非标准版本trim(both from 'xTomxx', 'x')Tom
btrim(string text [, characters text])textstring开头和结尾删除只包含 characters中字符(缺省是空白)的最长字符串。btrim('xyxtrimyyx', 'xy')trim
ltrim(string text [, characters text])text从字符串string的开头删除只包含characters 中字符(缺省是一个空白)的最长的字符串。ltrim('zzzytrim', 'xyz')trim
rtrim(string text [, characters text])text从字符串string的结尾删除只包含 characters中字符(缺省是个空白)的最长的字符串。rtrim('trimxxxx', 'x')trim

8)位置相关的函数

函数返回类型描述示例结果
position(substring in string)int指定子字符串的位置position('om' in 'Thomas')3
strpos(string, substring)int指定的子字符串的位置。和position(substring in string)一样,不过参数顺序相反。strpos('high', 'ig')2
left(str text, n int)text返回字符串的前n个字符。当n是负数时, 返回除最后|n|个字符以外的所有字符。left('abcde', 2)ab
right(str text, n int)text返回字符串中的后n个字符。当n是负值时, 返回除前|n|个字符以外的所有字符。right('abcde', 2)de

9) 字符串填充

函数返回类型描述示例结果
rpad(string text, length int [, fill text])text使用填充字符fill(缺省时为空白), 把string填充到length长度。 如果string已经比length长则将其从尾部截断。rpad('hi', 5, 'xy')hixyx
lpad(string text, length int [, fill text])text通过填充字符fill(缺省时为空白), 把string填充为length长度。 如果string已经比length长则将其尾部截断。lpad('hi', 5, 'xy')xyxhi

10)其他字符串函数

函数返回类型描述示例结果
repeat(string text, number int)textstring重复numberrepeat('Pg', 4)PgPgPgPg
split_part(string text, delimiter text, field int)text根据delimiter分隔string 返回

(三)日期函数

1) 当前日期时间:

CURRENT_DATE
CURRENT_TIME
CURRENT_TIMESTAMP
CURRENT_TIME(precision)
CURRENT_TIMESTAMP(precision)
LOCALTIME
LOCALTIMESTAMP
LOCALTIME(precision)
LOCALTIMESTAMP(precision)

CURRENT_TIMECURRENT_TIMESTAMP 返回带有时区的值;LOCALTIMELOCALTIMESTAMP 返回不带时区的值。

CURRENT_TIME,CURRENT_TIMESTAMPLOCALTIME,LOCALTIMESTAMP 可以有选择地获取一个精度参数,该精度导致结果的秒数域园整到指定小数位。 如果没有精度参数,将给予所能得到的全部精度。 一些例子:

SELECT CURRENT_TIME;
Result: 14:39:53.662522-05

SELECT CURRENT_DATE;
Result: 2001-12-23

SELECT CURRENT_TIMESTAMP;
Result: 2001-12-23 14:39:53.662522-05

SELECT CURRENT_TIMESTAMP(2);
Result: 2001-12-23 14:39:53.66-05

SELECT LOCALTIMESTAMP;
Result: 2001-12-23 14:39:53.662522

2) exact 相关

SELECT EXTRACT(HOUR FROM TIMESTAMP '2001-02-16 20:38:40');
Result: 20

其中hour 可以换成其他的字段, 如:

ISODOW  --表示是周几
MILLISECONDS  --秒
minute ---分
month
quarter 
week
year

(四)聚合函数

窗口函数在和当前行相关的一组表行上执行计算。 这相当于一个可以由聚合函数完成的计算类型。但不同于常规的聚合函数, 使用的窗口函数不会导致行被分组到一个单一的输出行;行保留其独立的身份。 在后台,窗口函数能够访问的不止查询结果的当前行。 下面的例子是按照不同的部门求取平均值: over()函数是用来标注范围的 , 如果不写 partition by,默认是所有行,

SELECT depname, empno, salary, avg(salary) OVER (PARTITION BY depname) FROM empsalary;
  depname  | empno | salary |          avg          
-----------+-------+--------+-----------------------
 develop   |    11 |   5200 | 5020.0000000000000000
 develop   |     7 |   4200 | 5020.0000000000000000
 develop   |     9 |   4500 | 5020.0000000000000000
 develop   |     8 |   6000 | 5020.0000000000000000
 develop   |    10 |   5200 | 5020.0000000000000000
 personnel |     5 |   3500 | 3700.0000000000000000
 personnel |     2 |   3900 | 3700.0000000000000000
 sales     |     3 |   4800 | 4866.6666666666666667
 sales     |     1 |   5000 | 4866.6666666666666667
 sales     |     4 |   4800 | 4866.6666666666666667
 
(10 rows)

下面是按照部门进行工资的排名,rank()的时候一定要写order by,不然rank列的值都是1

 select depname, empno,salary, rank() over (partition by depname order by salary desc) from test_yt.salaries 

表 9-53. 通用窗口函数

函数返回类型描述
row_number()bigint在其分区中的当前行号,从1计
rank()bigint有间隔的当前行排名;与它的第一个相同行的row_number相同
dense_rank()bigint没有间隔的当前行排名;这个函数计数对等组。
percent_rank()double precision当前行的相对排名: (rank - 1) / (总行数 - 1)
cume_dist()double precision当前行的相对排名:(前面的行数或与当前行相同的行数)/(总行数)

(五) 聚合函数

一个聚合函数从多个输入行中计算出一个结果。比如,我们有在一个行集合上计算count(数目), sum(总和),avg(均值),max(最大值), min(最小值)的函数。 如:

SELECT max(temp_lo) FROM weather;
函数参数类型返回类型描述
array_agg(expression)任意参数类型的数组输入值,包括空,连接到一个数组
avg(expression)smallintintbigintrealdouble precisionnumeric, or interval对于任何整数类型输入,结果都是numeric类型。 对于任何浮点输入,结果都是double precision类型。 否则和输入数据类型相同。所有输入值的均值(算术平均)
bit_and(expression)smallintintbigint, or bit和参数数据类型相同所有非 NULL 输入值的按位与(AND),如果全部输入值皆为 NULL ,那么结果也为 NULL 。
bit_or(expression)smallintintbigint, or bit和参数数据类型相同所有非 NULL 输入值的按位或(OR),如果全部输入值皆为 NULL ,那么结果也为 NULL 。
bool_and(expression)boolbool如果所有输入值都是真,则为真,否则为假。
bool_or(expression)boolbool如果至少有一个输入值为真,则为真,否则为假。
count(*) bigint输入行数
count(expression)任意bigint计算所有输入行中满足expression不为 NULL 的行数。
every(expression)boolbool等效于bool_and
json_agg(expression)anyjson聚合值作为JSON数组
json_object_agg(name, value)(any, any)json聚合名字/值对作为JSON对象
max(expression)任意数组、数值、字符串、日期/时间类型和参数数据类型相同有输入行中expression的最大值
min(expression)任意数组、数值、字符串、日期/时间类型和参数数据类型相同所有输入行中expression的最小值
string_agg(expression, delimiter)(texttext) or (byteabytea)和参数数据类型相同输入值连接成为一个字符串,用分隔符分开
sum(expression)smallintintbigintrealdouble precisionnumericinterval, or money对于smallintint参数,输出类型为bigint。 对于bigint参数,输出类型为numeric,否则和参数数据类型相同。所有输入行的expression总和。
xmlagg(expression)xmlxml连接 XML 值

四、运算符

(一)算数操作符

操作符描述例子结果
+2 + 35
-2 - 3-1
*2 * 36
/除(整数除法将截断结果)4 / 22
%模(求余)5 % 41
^幂(指数运算)2.0 ^ 3.08
|/平方根|/ 25.05
||/立方根||/ 27.03
!阶乘5 !120
!!阶乘(前缀操作符)!! 5120
@绝对值@ -5.05
&二进制 AND91 & 1511
|二进制 OR32| 335
#二进制 XOR17 # 520
~二进制 NOT~1-2
<<二进制左移1 << 416
>>二进制右移8 >> 22

(二) 位串操作符

操作符描述例子结果
||连接B'10001' ||B'011'10001011
&位与B'10001' & B'01101'00001
|位或B'10001'| B'01101'11101
#位异或B'10001' # B'01101'11100
~位非~ B'10001'01110
<<位左移B'10001' << 301000
>>位右移B'10001' >> 200100

(三) 逻辑运算符

AND | | OR | | NOT

(四)比较运算符略

五、常用的关键字或常用子句

(一) with 子句

(试了一下postgresl好像是不支持with语句的) with 语句相当于建立了一张临时虚拟表,但是不会被物理创建,用完即销毁;每个WITH子句中的辅助语句可以是一个SELECT,INSERTUPDATE 或 DELETE

WITH moved_rows AS (
    DELETE FROM products
    WHERE
        "date" >= '2010-10-01' AND
        "date" < '2010-11-01'
    RETURNING *
)
INSERT INTO products_log
SELECT * FROM moved_rows;

(二)distinct子句

如果声明了SELECT DISTINCT,那么就从结果集中删除所有重复的行 (每个有重复的组都保留一行)。

select distinct on (depname) depname  from test_yt.salaries

(三)all子句

all 与distinct相反

select all  (depname) depname  from test_yt.salaries

postgresql小结

(四)union子句

UNION 操作符用于合并两个或多个 SELECT 语句的结果并集 , 然后去除重复项, 如果不需要去除重复项的话 , 只要加上union all就可以了

 insert into test_yt.students1 values(1,'xiaoming'),(2,'xiaohua'),(3,'xiaoli');
 insert into test_yt.students values(1,'xiaoming'),(2,'xiaohuamao'),(3,'xiaoli');

 insert into test_yt.students values (4,'xiaozhangs');
  insert into test_yt.students1 values (4,'xiaozhangs1')

select name from test_yt.students1 union select name from test_yt.students

postgresql小结

(五)INTERSECT子句

INTERSECT就是查找有相同选项的交集

select name from test_yt.students1 INTERSECT  select name from test_yt.students

(六)except子句

这个语句就是再第一个select的结果中去掉第二个select的中的结果, 然后剩下的就是最终的结果

 insert into test_yt.students1 values(1,'xiaoming'),(2,'xiaohua'),(3,'xiaoli');
 insert into test_yt.students values(1,'xiaoming'),(2,'xiaohuamao'),(3,'xiaoli');

 insert into test_yt.students values (4,'xiaozhangs');
  insert into test_yt.students1 values (4,'xiaozhangs1')

select name from test_yt.students1 EXCEPT  select name from test_yt.students

结果是xiaohua和xiaozhangs1

(七)limit 和offset

limit限制了在前面几条中进行查询 , 1代表只查询第一条 ,all的话, 默认没有限制 , offset 代表偏移前面的几行 , 比如offset 1 代表从第二行开始查找

select * from test_yt.students limit 1 offset 1

(八)exists

EXISTS 运算符用于判断查询子句是否有记录,如果有一条或多条记录存在返回 True,否则返回 False。exists 可以和not连用

select name from test_yt.students where  exists (select name from test_yt.students1 where id  =1)

(九)in

in操作符允许您在 WHERE 子句中规定多个值。找出符合in 范围中存在的行,not in相反

select name from test_yt.students where name in('xiaoming','xiaoli','xiaosan')

(十)any,all

any 表示任意一个 ,all代表所有

select id from test_yt.students where id > any (select id from test_yt.students1 )

(十一) join

语法:

SELECT column1, column2, ...
FROM table1
JOIN table2 ON condition;

students列表是:

postgresql小结

students1的列表是:

postgresql小结

1) join| inner join

postgresql小结

postgresql小结

2) left join

postgresql小结

postgresql小结

3) right join 和left 相反

postgresql小结

4 )full outer join

postgresql小结

postgresql小结

(十二)is null 、is not null

 select * from test_yt.students1 where name is null;
  select * from test_yt.students1 where name is not null

(十三)like模糊查询

占位符:%  任意个数字符   _一个字符

查询 用户名以‘S’开头的员工信息
   Select * from emp where ename like 'S%'
 
查询用户名第二个字母是‘A’的员工信息
   select * from emp where ename like '_A%'
 
查询用户名第三个字母是‘A’的员工信息
   select * from emp where ename like '__A%'
 
包含A
   select * from emp where ename like '%A%'

六、视图

在 SQL 中,视图是基于 SQL 语句的结果集的可视化的表。 视图包含行和列,就像一个真实的表。视图中的字段就是来自一个或多个数据库中的真实的表中的字段。 您可以向视图添加 SQL 函数、WHERE 以及 JOIN 语句,也可以呈现数据,就像这些数据来自于某个单一的表一样。

(一) 创建视图

CREATE VIEW view_name AS  
SELECT column_name(s)  
FROM table_name  
WHERE condition

create view myview as select * from test_yt.students s ;
 select * from  myview

我觉得视图是有点像引用类型的变量的 , 如果表格的内容发生变化的话,view 里面查询的值也是会跟着变化的

(二) 查询视图

 select * from  myview

(三) 修改视图

1) rename

alter view myview rename to myviews;

2)其他

(四) 删除视图

drop view myview

七、易错注意点

(一)聚合函数使用场景

不能用于where子句中但是可以再having子句中使用 ,主要原因是- where 是在聚合之前选取行也就是控制哪些行进行聚合计算, having是在聚合之后才进行选取

SELECT city FROM weather WHERE temp_lo = max(temp_lo);     错误

正确的使用方法是:

SELECT city FROM weather
    WHERE temp_lo = (SELECT max(temp_lo) FROM weather);

(二)having 子句和where子句的区别

HAVING去除了一些不满足条件的组行。它与WHERE 不同:WHERE在使用GROUP BY之前过滤出单独的行, 而HAVING过滤由GROUP BY创建的行,见第三条的表格 比如:select depname from test_yt.salaries group by depname having depname='dev' having的话就是先分组,有dev personal 以及sales, 然后去掉不满足条件的personal,sales 如果使用where的话 , 就是先找到depname等于dev的, 然后再进行分组

(三)group by的注意点

group by的时候必须保证前面select 的column名 跟后面划分的一致,比如:

postgresql小结

这样的一张表 , 如果我直接

select * from test_yt.salaries group by depname 报错

正确的应该是

select depname from test_yt.salaries group by depname

(四)union子句和intersect、except

select_statement是任何不带 ORDER BYLIMITFOR NO KEY UPDATEFOR UPDATEFOR SHARE, 或 FOR KEY SHARE子句的SELECT语句。