PostgreSQL的50个案例!

目录

翻译自原文链接:PostgreSQL Query: Introduction,Explanation,and 50 Examples

本篇要点

  • 介绍一个SQL查询是怎么样的。
  • 如何在PostgreSQL中使用SQL查询。

我将提供50个SQL查询的例子,一起来学习吧。

什么是SQL

SQL是结构化查询语言Structured Query Language的缩写。 最初,它被称为SEQUEL(结构化英语查询语言),用于存储和处理数据库中的数据。 如今,SQL被广泛用于在关系数据库管理系统(RDBMS)中执行所有类型的数据操作。

SQL是一种功能强大的语言,我们可以在其中执行各种操作,如:

  • 执行查询
  • 获取数据
  • 在数据库中插入,更新和删除记录(DML操作)
  • 在数据库中创建新对象(DDL操作)
  • 在表,过程,函数和视图上设置权限
  • 还有更多...

什么是ANSI SQL标准?

美国国家标准协会(ANSI)于1986年创建了SQL标准,并于1987年被国际标准化组织(ISO)采纳。要使每个RDBMS都符合ANSI标准,它们都必须用尽可能相似的命令支持一些主要的命令,例如DML。

SQL遵循ANSI / ISO标准,但是不同的数据库系统使用不同版本的SQL语言。例如,在PostgreSQL中,我们可以使用RETURNING子句执行INSERT操作,而并非所有其他数据库都能做到。

即使如此,不同的数据库系统需要符合ANSI标准,所有数据库都以相同的方式支持命令(如DELETE,UPDATE,SELECT,INSERT),也就是说,语法应在任何地方都可以使用。

兼容性

INSERT为例,它符合SQL的标准,不同之处在于RETURNING子句是PostgreSQL扩展,类似的还有:

  • 在INSERT中使用WITH的能力。
  • 以及在ON CONFLICT中指定替代动作的能力。
  • 此外,标准不允许列名列表被省略,但PostgreSQL中不是所有的列都由VALUES子句或查询填充的情况。

SQL标准指定:只有id列存在的时候,OVERRIDING SYSTEM VALUE才可以被指定,但 PostgreSQL在任何情况下都允许该子句,如果不适用则将其忽略。

如果你想知道更多具体清晰的区别,可以查看PostgreSQL的文档。

50个例子

现在让我们学习探索一些常见实用的PostgreSQL的demo吧。

1. create table创建表

创建一个空表,由命令发起人拥有。

      postgres=# create table dummy_table(name varchar(20),address text,age int);
      CREATE TABLE

2. insert插入数据

向表中插入数据

        postgres=# insert into dummy_table values('XYZ','location-A',25);
        INSERT 0 1
        postgres=# insert into dummy_table values('ABC','location-B',35);
        INSERT 0 1
        postgres=# insert into dummy_table values('DEF','location-C',40);
        INSERT 0 1
        postgres=# insert into dummy_table values('PQR','location-D',54);
        INSERT 0 1

3. select查询,没有where子句

没有指定where条件,将会从数据库中获取所有的记录

        postgres=# select * from dummy_table;
        name |  address   | age 
        ---------+--------------+ -----
        XYZ   | location-A |  25
        ABC   | location-B |  35
        DEF   | location-C |  40
        PQR   | location-D |  54
        (4 rows)

4. udpate更新数据

PQR的年龄更新为50

        postgres=# update dummy_table set age=50 where name='PQR';
        UPDATE 1
        postgres=# select * from dummy_table;
        name |  address   | age 
        --------+--------------+-------
        XYZ  | location-A |  25
        ABC  | location-B |  35
        DEF  | location-C |  40
        PQR  | location-D |  50
        (4 rows)

为地址为location-D的人设置姓名和年龄

postgres=# update dummy_table set name='GHI',age=54 where address='location-D';
UPDATE 1
postgres=# select * from dummy_table;
 name |  address   | age 
------+------------+-----
 XYZ  | location-A |  25
 ABC  | location-B |  35
 DEF  | location-C |  40
 GHI  | location-D |  54
(4 rows)

postgres=# 

如果我们要更新所有记录的address和age,我们不需要使用where子句。

postgres=# update dummy_table set age=54,address='location-X';
UPDATE 4


postgres=# select * from dummy_table ;
 name |  address   | age 
------+------------+--------
 XYZ  | location-X |  54
 ABC  | location-X |  54
 DEF  | location-X |  54
 GHI  | location-X |  54
(4 rows)

postgres=# 

另外,可以使用RETURNING子句返回更新后的字段,建议在事务中执行该操作:BEGIN...COMMIT/ROLLBACK

postgres=# update dummy_table set age=30 where name='XYZ' returning age as age_no;
 age_no 
---------
      30
(1 row)

UPDATE 1

5. delete删除数据

删除行,可以指定where也可没有,如果缺少where条件,将会删除所有行,并保留一个空表,以下示例删除年龄为65的行。

postgres=# delete from dummy_table where age=65;
DELETE 1
postgres=# 

6. 比较符的运用

可以解决比较符号找到满足指定条件或值的列。

小于等于

postgres=# select * from dummy_table where age <=50;
 name |  address   | age 
------+------------+-----
 XYZ  | location-A |  25
 ABC  | location-B |  35
 DEF  | location-C |  40
 PQR  | location-D |  50
(4 rows)

大于等于

postgres=# select * from dummy_table where age>=50;
 name |  address   | age 
------+------------+-----
 PQR  | location-D |  50
(1 row)

不等于

postgres=# select * from dummy_table where age<>50;
 name |  address   | age 
------+------------+-----
 XYZ  | location-A |  25
 ABC  | location-B |  35
 DEF  | location-C |  40
(3 rows)

等于

postgres=# select * from dummy_table where age=50;
 name |  address   | age 
------+------------+-----
 PQR  | location-D |  50
(1 row)

7.select distinct去重查询

返回不重复的值。

没有去重之前

postgres=# select age from dummy_table order by 1;
 age 
-----
   1
   1
   2
   2
   3
(5 rows)

去重之后

postgres=# select distinct age from dummy_table order by 1;
 age 
-----
   1
   2
   3
(3 rows)

8. truncate清空表

清空一个表

postgres=# truncate table dummy_table;
TRUNCATE TABLE

9. drop 删除表

从数据库中移除这个表,包括该表的所有关联数据,索引,规则,触发器和约束。

postgresql=# drop table if exists dummy;
NOTICE:  table "dummy" does not exist,skipping
DROP TABLE

10. create view 创建视图

生成视图【伪表】,从表、子集或从基础表中选择的列形成的虚拟表。

postgres=# create or replace view vi as select * from dummy_table where age is NULL;
CREATE VIEW

11. 使用select语句创建表

postgres=# select 'My name  is X' as col1,10 as col2,'Address is -XYZ location' as col3  into new_table;
SELECT 1
postgres=# select * from new_table ;
     col1      | col2 |           col3           
---------------+------+--------------------------
 My name  is X |   10 | Address is -XYZ location
(1 row)

12. 设定超时

在GUC参数的帮助下,我们可以指定某个查询在特定的时间段后超时,中止,精确到毫秒。

postgresql=# set statement_timeout=10;
SET
postgresql=# select pg_sleep(20);
ERROR:  canceling statement due to statement timeout

13. 使用create sequence

该命令为序列号生成器,创建序列后,我们可以使用序列的nextval和currval函数将值插入表中。

postgres=# create sequence seq;
CREATE SEQUENCE
postgres=# create table tab(n int);
CREATE TABLE
postgres=# insert into tab values (nextval('seq'));
INSERT 0 1
postgres=# insert into tab values (currval('seq'));
INSERT 0 1
postgres=# insert into tab values (nextval('seq'));
INSERT 0 1
postgres=# select * from tab;
 n 
---
 1
 1
 2
(3 rows)

14. 导入blob数据类型

PostgreSQL不直接支持BLOB(二进制大对象),但是我们可以使用以下方法使用:

假设你在/home/edb文件夹中下载了PNG格式的图像。

[edb@localhost]$ ls /home/edb/mypic.png 
/home/edb/mypic.png

如果你想将他存到postgreSQL中,进入postgreSQL安装的bin目录下,链接psql终端:

postgres=# Create table testing(n int,n1 oid);
CREATE TABLE
postgres=# insert into testing values (1,lo_import('/home/edb/mypic.png'));
INSERT 0 1

lo_import()函数将命名文件加载到pg_largeobject中,并返回一个将引用大对象的OID【Object identifier】值。选择表仅显示OID,而不显示组成这张照片的bits。

15. ilike不区分大小写

ILIKE运算符是与LIKE运算符相似的匹配函数,但具有不区分大小写的有点。

postgres=# select * from ted;
  n  
-----
 TAR
 TaR
 Tar
 tar
(4 rows)

在where中使用ilike查询

postgres=# select * from ted where n ilike 'TAR%';
  n  
-----
 TAR
 TaR
 Tar
 tar
(4 rows)

16. 层次化查询

层次查询是指结果具有结构化或父子关系并以树结构显示的查询。 若要查看分层查询的工作方式,需要创建一个虚拟表。

create table test_table(  
  emp_no                int,ename                 char(5),job                       char(9),manager_no        int
);

向表中插入一些数据

insert into test_table values(10,'A1','CEO',null);
insert into test_table values(11,'B1','VP',10);
insert into test_table values(12,'B2',10);
insert into test_table values(13,'B3',10);
insert into test_table values(14,'C1','DIRECTOR',13);
insert into test_table values(15,‘C2’,‘DIRECTOR’,13);
insert into test_table values(16,'D1','MANAGER',15);
insert into test_table values(17,'E1','ENGINEER',11);
insert into test_table values(18,'E2',11);

创建完成之后,就可以按照下面的方法去层次化查询了。

17. 计算长度的函数

返回指定字符串变量中的字符数或字节数。

主查询

postgres=# select name,age from dummy_table;
 name | age 
------+-----
 XYZ  |  25
 ABC  |  35
 DEF  |  40
 PQR  |  54
 PQR  |    
(5 rows)

使用长度函数

postgres=# select length(name),length(age) from dummy_table;
 length | length 
--------+--------
      3 |      2
      3 |      2
      3 |      2
      3 |      2
      3 |       
(5 rows)

18. 发生has no destination for result data

如果我们收到了 query has no destination for result data的异常消息,我们可以使用以下方法去避免。

使用PERFORM

postgres=# create or replace function f(n int) 
returns int 
as 
$$ 
begin 
perform
now(); 
 return 1; 
 end; 
$$ language 'plpgsql';
CREATE FUNCTION
postgresql=# select f(9);
 f 
---
 1
(1 row)

在select into语句中使用变量

postgres=# create or replace function f(n int) 
returns int 
as 
$$ 
declare 
a date;
begin 
select now() into a;
raise notice ‘%s’,a; 
return 1; 
end; 
$$ language 'plpgsql';
CREATE FUNCTION
 
 
postgresql=# select f(9);
          NOTICE: 24-SEP-20 13:15:46.23388s
             f
            ---
            1
        (1 row)

19. 导出结果集

借助COPY命令,我们可以将数据从表导出到外部文本文件,也可以将数据从文本文件导入到表中。

导出结果集到text文件

postgres=#  copy dummy_table to '/tmp/abc.txt';
COPY 5
  
postgres=# \! cat /tmp/abc.txt
XYZ	location-A	25
ABC	location-B	35
DEF	location-C	40
PQR	location-D	50
CXC	1	50

从text文件导入数据

postgres=# copy dummy_table from '/tmp/abc.txt';
COPY 5

20. 展示所有的数据库

postgres=# select oid,datname from pg_database;
  oid     |  datname  
-----------+-----------
 13743 | postgres
     1     | template1
 13742 | template0
(3 rows) 

我们还可以在psql prompt下使用\l 命令列出所有的数据库名。

21. 检查语句执行时间

psql promt下使用\timing指令开启。

postgres=# \timing
Timing is on.

现在查询之后就会显示执行时间了。

postgres=# select * from dummy_table;
 name |  address   | age 
------+------------+--------
 XYZ  | location-A | 25
 ABC  | location-B | 35
 DEF  | location-C | 40
 PQR  | location-D | 50
 CXC  | 1               | 50
(5 rows)
 
Time: 0.440 ms
postgres=# 

22. 动态sql语句

  • 在查询中,动态SQL用于减少重复性任务。
  • 动态SQL查询不会缓存在内存中。
postgres=# do
postgres-# $$
postgres$# begin
postgres$# execute 'select * from dummy_table';
postgres$# end;
postgres$# $$;
DO

23. count计数

返回表中的行数,如果使用count(*)将包含null值,否则将排除。

postgres=# select count(*) from dummy_table;
 count 
-------
     5
(1 row)
 
postgres=# select count(avg) from dummy_table;
 count 
-------
     4
(1 row)

24. 分页 limit 和 offset

limit限制返回的记录数。

postgres=# select * from dummy_table  limit 1;
 name |  address   | age 
------+------------+-----
 XYZ  | location-A |  25
(1 row)

offset用于跳过我们不需要的数据。

postgres=# select * from dummy_table  offset 4;
 name | address | age 
------+---------+-----
 cxc  | 1       |  50
(1 row)

25. IF … ELSE 表达式

检查变量abc和xyz的值是否匹配,并显示结果,即150

postgres=# Do 
             $$
             Declare
              abc int;
              xyz int;
              begin
              abc:=100;
              xyz:=abc;
              if abc=xyz then 
               xyz=150;  
              raise notice '%',xyz;
             else
             end if;               
             end;
               $$
;
NOTICE:  150
DO

26. 使用join更新

如果我们要更新表X,但是需要基于另外一张表Y,我们可以按下面这样使用:

postgres=# create table X(n int,n1 char(10));
CREATE TABLE
postgres=# insert into X values (1,'abc');
INSERT 0 1
postgres=# insert into X values (2,'xyz');
INSERT 0 1
postgres=# insert into X values (3,'pqr');
INSERT 0 1

postgres=# create table Y(n int,n1 char(10));
CREATE TABLE

postgres=# insert into Y values (1,'');
INSERT 0 1
postgres=# insert into Y values (2,'');
INSERT 0 1

postgres=# insert into Y values (5,'axyz');
INSERT 0 1

postgres=# update Y set n1=X.n1 from X  where X.n=Y.n;
UPDATE 2
postgres=# select * from Y;
 n |     n1     
---+------------
 5 | axyz      
 1 | abc       
 2 | xyz       
(3 rows)

postgres=# 

27. inner join

将从两个(或多个)表中查找表中指定列数据匹配的行

postgres=# select *  from x inner join  y on  x.n1 = y.n1;
 n |     n1     | n |     n1     
---+------------+---+------------
 1 | abc        | 1 | abc       
 2 | xyz        | 2 | xyz       
(2 rows)

postgres=# 

28. case表达式

CASE表达式是通用条件表达式,类似于IF…ELSE语句。

postgres=# SELECT age,CASE age WHEN 25 THEN 'one'
              WHEN 50 THEN 'two'
              ELSE 'other'
       END
    FROM  dummy_table;
 age | case  
-----+-------
  25 | one
  35 | other
  40 | other
  50 | two
  50 | two
(5 rows)

29. 递归查询

递归查询用于处理层次查询或树状数据,下面创建测试数据:

CREATE TABLE emp_test (
  id int,ename varchar(255),emanager int
);

INSERT INTO emp_test VALUES (1,'abc',null);
INSERT INTO emp_test VALUES (2,'xyz',1);
INSERT INTO emp_test VALUES (3,'def',2);
INSERT INTO emp_test VALUES (4,'cde',1);
INSERT INTO emp_test VALUES (5,'qrs',2);
INSERT INTO emp_test VALUES (9,'iop',3);
INSERT INTO emp_test VALUES (10,'klm',4);

递归查询如下:

postgres=#WITH RECURSIVE emp_testnew  AS (
  SELECT id,ename,emanager
  FROM emp_test
  WHERE id = 2
  UNION ALL
  SELECT e.id,e.ename,e.emanager
  FROM emp_test e
  INNER JOIN emp_testnew e1 ON e1.id = e.emanager
)
SELECT *
FROM emp_testnew;

 id | ename | emanager 
----+-------+----------
  2 | xyz   |        1
  3 | def   |        2
  5 | qrs   |        2
  9 | iop   |        3
(4 rows)

postgres=# 

30. log查询

使用pg_stat_statements模块,我们可以跟踪所有SQL语句的执行统计信息。 为此,我们需要创建一个扩展并在postgresql.conf文件内添加shared_preload_libraries

postgres=# create extension pg_stat_statements;
CREATE EXTENSION


postgres=# show shared_preload_libraries ;
                           shared_preload_libraries                           
-------------------------------------------------
 $libdir/pg_stat_statements
(1 row)


postgres=# select query from pg_stat_statements where query like 'create table%';
-[ RECORD 1 ]-------------------
query | create table test(n int)

我们还可以通过启用postgresql.conf文件中的以下参数来配置PostgreSQL以生成日志输出

logging_collector = on
log_directory = 'log'
log_filename = ‘postgresql-%Y-%m-%d_%H%M%S.log'
log_destination = ‘stderr’
Log file will be created under the pg_log directory which resides under the data folder. 

[centos@tushar-ldap-docker bin]$ ls  data/log
postgresql-2020-09-17_150932.log  postgresql-2020-09-19_000000.log  
[centos@tushar-ldap-docker bin]$ 

查询记录的日志将被记录在这些文件中。

31. 使用变量

我们可以在psql prompt下使用声明变量:

postgres=# \set cond 50

在where条件中使用变量

postgres=# select * from dummy_table where age=:cond;
 name |  address   | age 
------+------------+-----
 PQR  | location-D |  50
(1 row)

postgres=# \set cond 50
postgres=# select :cond+100 ;
 ?column? 
----------
      150
(1 row)

32. 日期查询

详细:https://www.postgresql.org/docs/12/functions-datetime.html

postgres=# select now();
               now                
----------------------------------
 22-SEP-20 03:08:42.636385 +05:30
(1 row)

postgres=# select current_date;
 current_date 
--------------
 22-SEP-20
(1 row)

postgres=# select current_time;
     current_time      
-----------------------
 03:08:53.648466+05:30
(1 row)

我们还可以执行日期范围查询来查找值在两个时间戳之间的行:

postgres=# create table datetable(n int,n1 date);
CREATE TABLE

postgres=# insert into datetable values (1,'12-01-1980');
INSERT 0 1
postgres=# insert into datetable values (2,'12-01-2020');
INSERT 0 1
postgres=# insert into datetable values (3,'12-01-2000');
INSERT 0 1
postgres=# select * from datetable where n1 between '12-01-1980' and '12-01-2000';
 n |         n1         
---+--------------------
 1 | 12-JAN-80 00:00:00
 3 | 12-JAN-00 00:00:00
(2 rows)

33. return query

当声明一个PL / pgSQL函数返回某个数据类型的SETOF时,该返回由RETURN QUERY命令指定

postgres=# CREATE FUNCTION get(int) RETURNS SETOF integer AS
$BODY$
BEGIN
    RETURN QUERY SELECT age
                   FROM dummy_table
                  WHERE age >= $1  ;
    RETURN;
 END
$BODY$
LANGUAGE plpgsql;


postgres=# select * from get(9);
 get 
-----
  25
  35
  40
  50
(4 rows)

34. 并行查询

PostgreSQL中的并行查询使您可以利用许多CPU更快地完成查询。 这些GUC参数在postgresql.conf文件中设置

#max_parallel_maintenance_workers = 2   # taken from max_parallel_workers
#max_parallel_workers_per_gather = 2    # taken from max_parallel_workers
#parallel_leader_participation = on
#max_parallel_workers = 8               # maximum number of max_worker_processes that
                                                           # can be used in parallel operations


postgres=# create table ty(n int);
CREATE TABLE
postgres=# insert into ty values (generate_series(1,300000));
INSERT 0 300000

postgres=# analyze ty;
ANALYZE
postgres=# explain  select * from ty where n<=1;
                             QUERY PLAN                              
---------------------------------------------------------------------
 Gather  (cost=1000.00..4536.88 rows=30 width=4)
   Workers Planned: 1
   ->  Parallel Seq Scan on ty  (cost=0.00..3533.88 rows=18 width=4)
         Filter: (n <= 1)
(4 rows)

postgres=# 

35. 逻辑运算符

postgreSQL中有三个主要的逻辑运算符:AND OR NOT。

AND = when both boolean expressions are true then it will return TRUE
OR   = when any boolean expression is true then it will return TRUE
NOT = reverses the value of Boolean operator

36. 捕获重复的行

下面这个查询有两个重复的50:

 postgres=# select age from dummy_table;
 age 
-----
  25
  35
  40
  50
  50
(5 rows)

我们可以利用select ... having来找到重复的行。

postgres=#  select age,count(age) from dummy_table group by age having count(age)>1;
 age | count 
-----+-------
  50 |     2
(1 row)

37. 枚举

枚举类型是包含静态的,有序的一组值的数据类型。

postgres=# CREATE TYPE mood AS ENUM ('sad','ok','happy');
CREATE TYPE
postgres=# create table testi(n int,n1 mood);
CREATE TABLE
postgres=# insert into testi values (1,'happy');
INSERT 0 1
postgres=# insert into testi values (1,'sad');
INSERT 0 1
postgres=# insert into testi values (1,'ok');
INSERT 0 1

如果enum没有被指定,将会报错:

postgres=# insert into testi values (1,'happyo');
ERROR:  invalid input value for enum mood: "happyo"

38. pivot table

是一种通过将数据组织成更易于管理的格式来分析大量数据的有用方法。

CREATE TABLE newtb(id SERIAL,rowid varchar(10),attri varchar(10),val varchar(10));
INSERT INTO newtb(rowid,attri,val) values('t1','a1','v1');
INSERT INTO newtb(rowid,'a2','v2');
INSERT INTO newtb(rowid,'a3','v3');
INSERT INTO newtb(rowid,'a4','v4');
INSERT INTO newtb(rowid,val) values('t2','v5');
INSERT INTO newtb(rowid,'v6');
INSERT INTO newtb(rowid,'v7');
INSERT INTO newtb(rowid,'v8');

创建pivot table,你需要安装 tablefunc extension:

postgres=# create extension tablefunc;
CREATE EXTENSION

Select *
FROM crosstab(
  'select rowid,val
   from newtb
   where attri = ''a2'' or attri = ''a3''
   order by 1,2')
AS newtb(row_name varchar(10),category_1 varchar(10),category_2 varchar(10),category_3 varchar(10));
 row_name | category_1 | category_2 | category_3 
----------+------------+------------+--------------------------
   t1       |              v2        |            v3    | 
   t2       |             v6         |             v7   | 
(2 rows)

39. self join自连接

当我们针对自身联接表时,这称为自联接。 可以使用INNER JOINLEFT JOIN完成。 当比较同一表中的行时,自连接非常有用。

postgres=# create table emp1(emp_id int,firstname char(10),lastname char(10),manager_id int);
CREATE TABLE
postgres=# 
postgres=# 
postgres=# insert into emp1 values(1,'ABC','XYZ',NULL);
INSERT 0 1
postgres=# insert into emp1 values(2,'TYU','BGV',1);
INSERT 0 1
postgres=# insert into emp1 values(3,'TEU','ZZV',1);
INSERT 0 1
postgres=# insert into emp1 values(4,'REU','AZV',2);
INSERT 0 1
postgres=# insert into emp1 values(5,'QREU','WZV',2);
INSERT 0 1
postgres=# insert into emp1 values(6,'DREU','QZV',3);
INSERT 0 1


postgres=# select a.firstname,b.lastname from emp1 a inner join emp1 b on a.emp_id=b.manager_id order by 1 ;
 firstname  |  lastname  
------------+------------
 ABC        | ZZV       
 ABC        | BGV       
 TEU        | QZV       
 TYU        | WZV       
 TYU        | AZV       
(5 rows)

postgres=# 

40. 父子递归

依靠 common table expressions (CTE),我们可以进行父子查询。

postgres=# CREATE TABLE recu_pc (
 id SERIAL PRIMARY KEY,name varchar(10) NOT NULL,parent_id integer );
CREATE TABLE
 
postgres=# insert into recu_pc values (1,'Grandmother',NULL);
INSERT 0 1
postgres=# insert into recu_pc values (2,'mother',1);
INSERT 0 1
postgres=# insert into recu_pc values (3,'daughter',2);
INSERT 0 1

 
postgres=# WITH RECURSIVE rec_q (id) as
(          
  SELECT recu_pc.id,recu_pc.name from recu_pc where name='mother'
  UNION ALL
  SELECT recu_pc.id,recu_pc.name from rec_q,recu_pc where recu_pc.parent_id = rec_q.id
  )
SELECT *
FROM rec_q;
 id |   name   
----+----------
  2 | mother
  3 | daughter
(2 rows)

41. 定义变量

使用匿名块 anonymous block,我们可以定义传入query的变量

postgres=# do 
$$
declare 
a int;
begin 
select age into a from dummy_table  
where name ='XYZ';
raise notice '%',a; 
end;
$$;
NOTICE:  25
DO

42. prepare语句

用于优化性能。 当执行PREPARE语句时,不仅会对其进行解析,而且还会对其进行分析,并且当我们执行EXECUTE命令时,将计划并执行准备好的语句。

postgres=# prepare test(int) as 
select * from dummy_table where age=$1;
PREPARE
 
postgres=# execute test(50);
 name |  address   | age 
------+------------+---------
 PQR  | location-D |  50
 CXC | 1                |  50
(2 rows)

43. 检查null值

postgres=# select * from dummy_table;
 name |  address   | age 
------+------------+-----
 XYZ  | location-A |  25
 ABC  | location-B |  35
 DEF  | location-C |  40
 PQR  | location-D |  54
 PQR  | location-D |    
(5 rows)

找到age值为null的记录

postgres=# select name from dummy_table where age is null;
 name 
------
 PQR
(1 row)

44. 使用exists检查查询是否为空

我们可以使用EXISTS检查查询是否为空。 EXISTS是一个布尔运算符,用于测试子查询中行的存在。

postgres=# select exists(select * from (select 'true' where 1=3));
 exists 
--------
 f
(1 row)

postgres=# select exists(select * from (select 'true' where 1=1));
 exists 
--------
 t
(1 row)

45. 语句执行时间日志

要查看查询的执行时间日志,您需要启用相关的GUC参数:

postgresql=# set log_min_duration_statement=0;
SET
postgresql=# set log_statement='all';
SET

现在,如果我们检查在data / log文件夹中创建的日志文件,我们应该会收到执行时间消息

2020-09-23 02:47:12.887 +0530 [30737] LOG:  statement: create table gg1(n int);
2020-09-23 02:47:12.888 +0530 [30737] LOG:  duration: 1.165 ms
2020-09-23 02:47:28.092 +0530 [30737] LOG:  statement: insert into gg1 values (generate_series(1,100000));
2020-09-23 02:47:28.182 +0530 [30737] LOG:  duration: 94.858 ms 

46. 在shell脚本中执行查询

我们可以使用bash shell脚本执行psql命令。 下面的示例是一个print.sh文件,我们在其中执行两个数字的加法运算

[edb@tushar-ldap-docker misc]$ cat print.sh 
#!/bin/bash
# This script is used to print addition of 2 numbers
# 1. Get path of bin directory.
BIN_DIRECTORY='/usr/psql-11/bin/'
$BIN_DIRECTORY/psql -U  postgres -p 5432 -d postgres -c 'select  5+5;'

执行脚本

edb@tushar-ldap-docker misc]$ print.sh 
 ?column? 
----------
       10
(1 row)

47. union操作符

用于合并两个或多个SQL语句的结果,同时消除重复的行。

postgres=# create table tab1(n int); 
CREATE TABLE

postgres=# insert into tab1 values (1),(2);
INSERT 0 2
postgres=# create table tab2(n int); 
CREATE TABLE

postgres=# insert into tab2 values (3),(2);
INSERT 0 2

postgres=# select * from tab1 union select * from tab2;
 n 
---
 2
 1
 3
(3 rows)

48. 查询优化的命令

explain

explain命令显示一条语句的执行计划。 在explain计划中添加analyze关键字将执行查询并显示真实的行数和真实的运行时间

vacuum

vacuum命令基本上删除所有由update删除或过时但未从表中物理删除的元组。

analyze

analyze收集有关数据库中表内容的统计信息

Database indexes

创建数据库索引可以避免全表扫描。

PostgreSQL configuration parameters

我们可能会使用某些PostgreSQL配置参数来获得更好的性能,例如max_connectionscheckpoint_segmentswork_mem和random_page_cost

49. alter table添加或修改列

添加或修改列

postgres=# alter table dummy_table add col1 int;
ALTER TABLE
postgres=# alter table dummy_table  rename col1 to col2;
ALTER TABLE
postgres=#  alter table dummy_table alter column col2 type char;
ALTER TABLE
postgres=# alter table dummy_table drop column col2;
ALTER TABLE

50. comment注释

使用comment语句提供有关数据库对象的注释

postgres=# Comment on table dummy_table  is 'This was a testing table';
COMMENT

postgres=# Comment on function f is 'Don''t update the function please' ;
COMMENT

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


在正式开始之前,我们先来看下 MySQL 服务器的配置和版本号信息,如下图所示: “兵马未动粮草先行”,看完了相关的配置之后,我们先来创建一张测试表和一些测试数据。 -- 如果存在 person 表先删除 DROP TABLE IF EXISTS person; -- 创建 person 表,其中
&gt; [合辑地址:MySQL全面瓦解](https://www.cnblogs.com/wzh2010/category/1859594.html &quot;合辑地址:MySQL全面瓦解&quot;) # 1 为什么需要数据库备份 - 灾难恢复:当发生数据灾难的时候,需要对损坏的数据进行恢复和
物理服务机的CPU、内存、存储设备、连接数等资源有限,某个时段大量连接同时执行操作,会导致数据库在处理上遇到性能瓶颈。为了解决这个问题,行业先驱门充分发扬了分而治之的思想,对大库表进行分割,&#xA;然后实施更好的控制和管理,同时使用多台机器的CPU、内存、存储,提供更好的性能。而分治有两种实现方式:垂直拆
1 回顾 上一节我们详细讲解了如何对数据库进行分区操作,包括了 垂直拆分(Scale Up 纵向扩展)和&#160;水平拆分(Scale Out 横向扩展) ,同时简要整理了水平分区的几种策略,现在来回顾一下。 2 水平分区的5种策略 2.1 Hash(哈希) 这种策略是通过对表的一个或多个列的Ha
navicat查看某个表的所有字段的详细信息 navicat设计表只能一次查看一个字段的备注信息,那怎么才能做到一次性查询表的信息呢?SELECT COLUMN_NAME,COLUMN_COMMENT,COLUMN_TYPE,COLUMN_KEY FROM information_schema.CO
文章浏览阅读4.3k次。转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/52768613前言:数据库每天的数据不断增多,自动删除机制总体风险太大,想保留更多历史性的数据供查询,于是从小的hbase换到大的hbase上,势在必行。今天记录下这次数据仓库迁移。看下Agenda:彻底卸载MySQL安装MySQL_linux服务器进行数据迁移
文章浏览阅读488次。恢复步骤概要备份frm、ibd文件如果mysql版本发生变化,安装回原本的mysql版本创建和原本库名一致新库,字符集都要保持一样通过frm获取到原先的表结构,通过的得到的表结构创建一个和原先结构一样的空表。使用“ALTER TABLE DISCARD TABLESPACE;”命令卸载掉表空间将原先的ibd拷贝到mysql的仓库下添加用户权限 “chown . .ibd”,如果是操作和mysql的使用权限一致可以跳过通过“ALTER TABLE IMPORT TABLESPACE;”命令恢_alter table discard tablespace
文章浏览阅读225次。当MySQL单表记录数过大时,增删改查性能都会急剧下降,可以参考以下步骤来优化:单表优化除非单表数据未来会一直不断上涨,否则不要一开始就考虑拆分,拆分会带来逻辑、部署、运维的各种复杂度,一般以整型值为主的表在千万级以下,字符串为主的表在五百万以下是没有太大问题的。而事实上很多时候MySQL单表的性能依然有不少优化空间,甚至能正常支撑千万级以上的数据量:字段尽量使用TINYINT、SMALLINT、MEDIUM_INT作为整数类型而非INT,如果非负则加上UNSIGNEDVARCHAR的长度只分配_开发项目 浏览记录表 过大怎么办
文章浏览阅读1.5k次。Mysql创建、删除用户MySql中添加用户,新建数据库,用户授权,删除用户,修改密码(注意每行后边都跟个;表示一个命令语句结束):1.新建用户登录MYSQL:@>mysql -u root -p@>密码创建用户:mysql> insert into mysql.user(Host,User,Password) values("localhost_删除mysql用户组
MySQL是一种开源的关系型数据库管理系统,被广泛应用于各类应用程序的开发中。对于MySQL中的字段,我们需要进行数据类型以及默认值的设置,这对于数据的存储和使用至关重要。其中,有一个非常重要的概念就是MySQL字段默认字符串。 CREATE TABLE `my_...
MySQL是一个流行的开源关系型数据库管理系统,广泛应用于Web应用程序开发、数据存储和管理。在使用MySQL时,正确设置字符集非常重要,以确保数据的正确性和可靠性。 在MySQL中,字符集表示为一系列字符和字母的集合。MySQL支持多种字符集,包括ASCII、UTF...
MySQL存储函数 n以内偶数 MySQL存储函数能够帮助用户简化操作,提高效率,常常被用于计算和处理数据。下面我们就来了解一下如何使用MySQL存储函数计算n以内的偶数。 定义存储函数 首先,我们需要定义一个MySQL存储函数,以计算n以内的偶数。下...
MySQL是一个流行的关系型数据库管理系统,基于客户机-服务器模式,可在各种操作系统上运行。 MySQL支持多种字符集,不同的字符集包括不同的字符,如字母、数字、符号等,并提供不同的排序规则,以满足不同语言环境的需求。 //查看MySQL支持的字符集与校对规...
在MySQL数据库中,我们有时需要对特定的字符串进行截取并进行分组统计。这种操作对于数据分析和报表制作有着重要的应用。下面我们将讲解一些基本的字符串截取和分组统计的方法。 首先,我们可以使用substring函数对字段中的字符串进行截取。假设我们有一张表stude...
MySQL提供了多种字符串的查找函数。下面我们就一一介绍。 1. LIKE函数 SELECT * FROM mytable WHERE mycolumn LIKE 'apple%'; 其中"apple%"表示以apple开头的字符串,%表示任意多个字符...
MySQL 是一种关系型数据库管理系统,广泛应用于各种不同规模和类型的应用程序中。在 MySQL 中,处理字符串数据是很常见的任务。有时候,我们需要在字符串的开头添加一定数量的 0 ,以达到一定的位数。比如,我们可能需要将一个数字转换为 4 位或 5 位的字符串,不足的...
MySQL是一种流行的关系型数据库管理系统,支持多种数据类型。以下是MySQL所支持的数据类型: 1. 数值型数据类型: - TINYINT 保存-128到127范围内的整数 - SMALLINT 保存-32768到32767范围内的整数 - MEDIU...
MySQL中存储Emoji表情字段类型 在现代互联网生态中,表情符号已经成为人们展示情感和思想的重要方式之一,因此将表情符号存储到数据库中是一个经常出现的问题。MySQL作为最流行的开源关系型数据库管理系统之一,也需要能够存储和管理这些表情符号的字段类型。 UT...
MySQL是一种关系型数据库管理系统。在MySQL数据库中,有多种不同的数据类型。而其中,最常见的数据类型之一就是字符串类型。在MySQL中,字符串类型的数据通常会被存储为TEXT或VARCHAR类型。 首先,让我们来看一下VARCHAR类型。VARCHAR是My...
MySQL字符串取整知识详解 MySQL是一种开源的关系型数据库管理系统,广泛应用于各个领域。在使用MySQL过程当中,我们经常需要对数据进行取整操作。本文将介绍如何使用MySQL字符串取整来处理数据取整问题。 什么是MySQL字符串取整? MySQL...