sql查询语句中主要包括selectwhereorder byjoinuniongroup byhavinglimit等关键词。

语法顺序

sql查询书写顺序如下所示:

1
2
3
4
5
6
7
8
9
10
select <字段名>
from <表名>
join <表名>
on <连接条件>
where <筛选条件>
group by <字段名>
having <筛选条件>
union
order by <字段名>
limit <限制行数>

selectfrom是必须的,其他的关键词可以省略。

执行顺序

  1. from

首先会根据from后的表名,生成一个虚拟表table1.

  1. joinon

join条件包括左连接left join、右连接right join、全连接full join、内连接inner join和交叉连接cross join
join后的表名记作table2,那么以from产生的table1为基准,左连接就是选择table1的全部和table2满足on条件的部分形成一张新表table3。
例如这里有两张表students和class。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
postgres=# select * from students;
name | id | age
----------+----+-----
zhangsan | 1 | 10
lisi | 2 | 11
sunqi | 7 | 20
(3 rows)

postgres=# select * from class;
name | id | class
----------+----+-------
zhangsan | 1 | 1
lisi | 2 | 1
wangwu | 3 | 1
zhaoliu | 4 | 2
(4 rows)

通过左连接,得到结果如下:

1
2
3
4
5
6
7
postgres=# select * from students left join class on students.id = class.id;
name | id | age | name | id | class
----------+----+-----+----------+----+-------
zhangsan | 1 | 10 | zhangsan | 1 | 1
lisi | 2 | 11 | lisi | 2 | 1
sunqi | 7 | 20 | | |
(3 rows)

其他的连接方式同理,右连接就是选择table2的全部,全连接是取两张表的并集,内连接是取交集。
需要注意一下的是,交叉连接是取笛卡尔积,并且交叉连接是不能和on同时使用的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
postgres=# select * from students cross join class;
name | id | age | name | id | class
----------+----+-----+----------+----+-------
zhangsan | 1 | 10 | zhangsan | 1 | 1
zhangsan | 1 | 10 | lisi | 2 | 1
zhangsan | 1 | 10 | wangwu | 3 | 1
zhangsan | 1 | 10 | zhaoliu | 4 | 2
lisi | 2 | 11 | zhangsan | 1 | 1
lisi | 2 | 11 | lisi | 2 | 1
lisi | 2 | 11 | wangwu | 3 | 1
lisi | 2 | 11 | zhaoliu | 4 | 2
sunqi | 7 | 20 | zhangsan | 1 | 1
sunqi | 7 | 20 | lisi | 2 | 1
sunqi | 7 | 20 | wangwu | 3 | 1
sunqi | 7 | 20 | zhaoliu | 4 | 2
(12 rows)

如果有多个join,就把前一次生成的表作为基准,再重复执行这一流程,直到能够合并出来一张表。

  1. where

在执行过fromjoin后,会生成一张新的虚拟表(如果没有join过程,就还是from产生的表),记作table3,where是在table3的基础上对表中的数据按照条件过滤一次,将符合条件的数据生成一张新的表,记作table4。

  1. group by

分组操作是在where之后执行的,将table4的列按照语句中的列名进行分组操作,最后生成了一张新表table5。

  1. having

分组之后的新表table5还可以再根据having后的条件再进行过滤,然后将符合条件的数据再生成一张新表table6。

  1. select

等前面的语句都执行完毕了,最后才通过select操作对最后生成的表读取对应的列,比如读取table6中的对应列,然后将这些列再组织成一张新表table7,如果没有后续的操作的话,就会将table7返回给客户端展示了。

  1. union

union操作是用来合并多个select结果的,union后面跟着的也是一个完整的查询语句,重复执行上述步骤,获得一个新表table7.1。然后将table7和table7.1重新合并成一个新表table8。也就说,union连接的是两个select查询出的表,将两张表再进行合并一次。

  1. order by

到这里时,就已经开始返回查询到的数据了,不再会对表中数据进行增删。order by是排序操作,决定了如何返回表中数据(升序还是降序)。

  1. limit

指定返回多少行。