数据库版本:KingbaseES V008R006C008B0014
简介
SELECT语句是用于从一个或多个表中检索数据的操作,它作为数据库DQL语言,可以通过特定条件从表中检索数据。本篇文章以kingbase为例介绍select的详细用法。
文章目录如下
1. 基本语法
2. 条件过滤
2.1. 比较运算符
2.2. 逻辑运算符
2.3. 模糊匹配
2.4. 成员运算符
2.5. 范围匹配
2.6. 检查匹配
3. 聚合函数
4. 数据排序
5. 分组查询
6. 子查询
7. 连接查询
7.1. 内连接
7.2. 外连接
8. 总结
1. 基本语法
SELECT 的基本语法如下:
SELECT
列名 --需要查询的列,*表示所有列
FROM
表名; --需要查询的表
- 以分号结尾(在SQL中,分号表示结束符)
示例:
这种最简单的写法查询的数据也是最繁杂,特别当表存在成千上万行时是无法利用人力寻找的,所以需要一个过滤条件。在SQL通过关键字where来过滤:
SELECT
列名
FROM
表名
WHERE
列名 = '成都市'; --直接查询成都
除了条件过滤,SELECT还支持排序、分组、聚合等操作,下面依次介绍。
2. 条件过滤
在SELECT语句中,使用where子句来指定过滤条件,语法为:
SELECT
列名 --需要查询的列,*表示所有列
FROM
表名 --需要查询的表
WHERE
条件; --指定条件过滤
这里的条件可以是比较运算符、逻辑运算符、模糊匹配、成员运算符等。
2.1. 比较运算符
比较运算符包括:
大于(>)
小于(<)
等于(=)
不等于(<>或!=)
大于等于(>=)
小于等于(<=)
举个例子,查询 id 列大于10的信息(使用 >)
SELECT
*
FROM
表名
WHERE
id > 10; --指定条件
查询 name 列等于 '成都市' 的信息(使用 =)
- 注意:数字不加引号,字符必须加引号
SELECT
*
FROM
表名
WHERE
name = '成都市'; --指定条件
2.2. 逻辑运算符
逻辑运算符包括:
与(AND):满足全部要求
或(OR) :满足部分要求
非(NOT):取反
举个例子,查询 name = 成都市,且 id = 1 的信息(使用 AND)
SELECT
*
FROM
表名
WHERE
name = '成都市'
AND --使用逻辑运算符
id = 1;
查询 name = 成都市,或者 id = 2 的信息(使用 OR)
SELECT
*
FROM
表名
WHERE
name = '成都市'
OR --使用逻辑运算符
id = 2;
查询成都市和资阳市以外的城市信息(使用 NOT)
SELECT
*
FROM
表名
WHERE
NOT name = '成都市' --取反
AND
NOT name = '资阳市'; --取反
2.3. 模糊匹配
模糊匹配分为:
左模糊(%ab):以ab结尾的字符
右模糊(ab%):以ab开头的字符
全模糊(%ab%):包含ab的字符
语法为:
SELECT
列名
FROM
表名
WHERE
列名 LIKE '模糊匹配'; --模糊匹配某列
举个例子,匹配 description 列以 '光' 结尾的数据(使用左模糊)
SELECT
*
FROM
si_chuan
WHERE
description LIKE '%光'; --左模糊
匹配 description 列包含 '光' 的数据(使用全模糊)
SELECT
*
FROM
si_chuan
WHERE
description LIKE '%光%'; --全模糊
2.4. 成员运算符
成员运算符分为:
IN:判断多个值
NOT IN:判断多个值取反
【案例一】过滤多个值
SELECT
*
FROM
si_chuan
WHERE
id IN(1, 2, 3); --同时查询id为1/2/3的值
【案例二】不查询多个值
SELECT
*
FROM
si_chuan
WHERE
id NOT IN(1, 2, 3); --查询id不包含1/2/3的值
2.5. 范围匹配
范围匹配一般使用
BETWEEN 开始值 AND 结束值
当需要查询 id 为5~10的数据时,一般采用比较+逻辑运算符:
SELECT
*
FROM
si_chuan
WHERE
id >= 5 AND id <=10;
使用 BETWEEN 语法
SELECT
*
FROM
si_chuan
WHERE
id BETWEEN 5 AND 10;
2.6. 检查匹配
检查匹配包括
IS NULL:查询为空的数据
IS NOT NULL:查询不为空的数据
EXISTS:判断子查询是否返回了结果集
【案例一】查询 description 列为空的数据
SELECT
*
FROM
si_chuan
WHERE
description IS NULL;
【案例二】查询 description 列不为空的数据
SELECT
*
FROM
si_chuan
WHERE
description IS NOT NULL;
【案例三】判断子查询不为空
SELECT * FROM si_chuan WHERE EXISTS (SELECT * FROM t1);
- 如果子查询为空则返回空
- 如果子查询不为空则返回正常结果
3. 聚合函数
- 聚合函数用于对一组数值进行计算,并返回单个值作为结果,通常对某列作聚合运算。
【案例一】统计某张表行数(包括空行)
SELECT COUNT(*) FROM 表名;
【案例二】计算某列的总值(该列必须为数值类型)
SELECT SUM(列名) FROM 表名;
【案例三】计算某列的平均值(该列必须为数值类型)
SELECT AVG(列名) FROM 表名;
【案例四】查看某列的最大值(该列必须为数值类型)
SELECT MAX(列名) FROM 表名;
【案例五】查看某列的最小值(该列必须为数值类型)
SELECT MIN(列名) FROM 表名;
【案例六】对某列去重
SELECT DISTINCT(列名) FROM 表名;
4. 数据排序
SELECT 语言可以对任何类型的数据进行排序,包括数值、字符串、日期和其他数据类型。
- 数值类型:排序是基于数值的大小进行的;
- 字符串类型:排序是基于字母顺序进行的;
- 日期类型:排序是基于日期的先后顺序进行。
排序不需要加 WHERE 条件,语法如下:
SELECT
*
FROM
表名
ORDER BY 列名 [升序/降序];
- ASC:表示升序(默认)
- DESC:表示降序
【案例一】对 "薪资" 列升序
SELECT * FROM 表名 ORDER BY 薪资; --默认升序
SELECT * FROM 表名 ORDER BY 薪资 ASC;
【案例二】对 "入职日期" 列降序
SELECT * FROM 表名 ORDER BY 入职日期 DESC;
【案例三】对多字段排序
SELECT
*
FROM
表名
ORDER BY
薪资 ASC,
年龄 ASC,
入职日期 DESC;
上述排序的优先级为:薪资>年龄>入职日期,所以只有当高优先级出现相同的值后,才会对下一级进行排序。
5. 分组查询
分组查询是对数据库中的数据进行分组计算,并返回汇总数据的过程。通常搭配聚合函数一起使用,直接使用相当于去重。
比如:直接对 "性别" 列分组(相当于去重)
SELECT
性别
FROM
表名
GROUP BY 性别;
对于聚合函数的应用,比如查询每类 "学历" 的总薪资
SELECT
学历, SUM(薪资)
FROM
表名
GROUP BY 学历;
- 查询2列:学历、薪资,并对薪资求和。如果不分组则对所有人薪资求和,但对学历分组,那么会对不同学历分别求和。
又或者查询每类学历目前的人数
SELECT
学历, COUNT(*) AS 人数
FROM
表名
GROUP BY 学历;
- 同样查询2列数据,count表示统计行数,对学历分组后就会自动对不同学历统计行数。
实际上分组就是将某列的数据去重,然后计算这列数据的平均值、最大值、最小值等等,非常的简单。需要注意的是,分组后面如果带有条件,是不能使用where的,而是having。
使用上面的例子,统计每类学历人数后,过滤人数大于2500的数据
SELECT
学历, COUNT(*) AS 人数
FROM
表名
GROUP BY 学历
HAVING --分组后过滤使用having,而不是where
人数 > 2500;
如果是排序则可以不使用 having
SELECT
学历, COUNT(*) AS 人数
FROM
表名
GROUP BY 学历
ORDER BY 人数;
6. 子查询
子查询实际上就是在一个查询中嵌套另外一个查询,这样在内部的查询结果可以影响到外部的查询操作。
SELECT * FROM 表名 WHERE id = (子查询);
比如通过表2的结果来查询表1
SELECT
*
FROM
表1
WHERE
列名 IN (
SELECT 列名 FROM 表2 WHERE 条件
);
子查询同样可以应用到投影列
SELECT
id,
name,
(SELECT MAX(薪资) FROM 表2)
FROM
表1;
- 将表2最大工资放到查询列中
还可以将子查询作为表来使用
SELECT
学历, AVG(薪资)
FROM
(SELECT * FROM emp WHERE 薪资 > 15000) --子查询的数据作为表
GROUP BY 学历;
7. 连接查询
连接查询用于在多个表之间建立关联,并检索出满足指定条件的记录。可以通过将两个或多个表的列进行比较来确定它们之间的关系,并返回相关联的记录。
比如直接查询2张表:
t1 和 t2 表分别包含3行数据,直接查询2张表会进行交叉连接操作(称为笛卡尔积)。交叉连接会返回2张表中所有可能的组合,即将表 t1 的每一行与表 t2 的每一行进行匹配,生成一个新的结果集,所呈现的行数为 3*3=9 行。
正是因为直接查询2张表会形成笛卡尔积,当表数据过万时所查询的数据极为复杂且易用性太差,所以需要通过连接查询来简化数据。
7.1. 内连接
内连接查询基于两个或多个表之间的相同值将符合条件的行连接起来,只有那些在所有连接的表中都存在匹配值的行才会被返回。
SELECT
列名
FROM
表1 INNER JOIN 表2 --连接2张表
ON
表1.列名 = 表2.列名 --连接条件:相同类型的列
INNER JOIN 表3 --连接3张表
表2.列名 = 表3.列名 --连接条件:相同类型的列
INNER JOIN 表4 --连接4张表
表3.列名 = 表4.列名; --连接条件:相同类型的列
使用条件 t1.id = t2.id,从字面来理解两张表的id列相同的数据,也就是只查询相同的数据。
注意:id 列不是固定的,可以是任意列,但是数据类型必须相同。
还有一种写法,使用where条件
SELECT
列名
FROM
表1,表2,表3
WHERE
表1.列名 = 表2.列名
AND
表2.列名 = 表3.列名;
这种方法不需要 inner join 关键字,只需要加条件即可,使用更简单。
7.2. 外连接
上述通过内连接来查询数据相同的行,对于某些场景无法完全应用,比如同时查询 "表1" 和 "表2",需要查询 "表1" 的全部信息和与 "表2" 相同数据的信息,则需要使用外连接。
左连接:显示左表全部数据和右表与左表相同的数据
SELECT
列名
FROM
表1 LEFT JOIN 表2
ON
表1.列名 = 表2.列名;
表1在左边,所以查询表1的所有信息,存在条件 表1.列名 = 表2.列名,所以只显示与表1相同数据的表2
右连接:显示右表全部数据和左表与右表相同的数据
SELECT
列名
FROM
表1 RIGHT JOIN 表2
ON
表1.列名 = 表2.列名;
8. 总结
SELECT 语句主要用于查询某张表的数据,可以指定要查询的列以及可选的过滤条件、排序顺序和其他参数。通过2~5章节的基础学习可以了解SELECT的基本用法,但可能没办法将每种语法串起来,所以参考如下图:
- 蓝色表示必选
- 橙色表示二选一
- 灰色表示可选
select 后面可以查询某列或者某列的聚合函数,表名后面的参数是可选的,表名后面可以接where条件或分组或排序等,也可以全部使用。全部使用的顺序参考示图箭头:
where > group by > order by
学习基本语法后再深入学习多表查询(章节6、7)。多表查询记住一个要点就行:加条件。比如内连接:
SELECT
*
FROM
表1,表2
WHERE
表1.列 = 表2.列;
直接查询2张表会出现笛卡尔积,但只要将2张表的列数据作=条件,那么只会显示两列相同的数据,再根据当前的数据继续过滤即可。