目录
数据查询
select语句的一般格式如下:
select (all|distinct) <目标列表达式> [别名][,<目标列表达式> [别名]]...
from <表名或视图名> [别名][,<表名或视图名> [别名]]...|(<select语句>) [as] <别名>
[where <条件表达式>]
[group by <列名1> [having <条件表达式>]]
[order by <列名2> [asc|desc]]
[limit <行数1> [offset <行数2>]];
- select语句就是展示所要查询的语句,select什么,就看到什么
- group by子句会将结果按<列名1>的值进行分组,属性列值相等的为一组,通常会使用聚集函数;如果有having语句,则只有满足指定条件的组才能输出
- order by子句,按照<列名2>的值进行排序;asc升序(默认),desc降序
- limit子句,限制select语句查询结果的数量为<行数1>,offset表示在<行数1>忽略<行数2>行,offset可以省略,表示不忽略任何行
下面以”学生选课“数据库为例,说明select语句的各种用法
单表查询
1.选择表中的若干列
查询指定列:
- 查询全体学生的学号和姓名
select sno,sname from student;
查询全部列:
- 查询全体学生的详细记录
select * from student;
///等价于
select sno,sname,ssex,sbirthdate,smajor from student;
查询经过计算的值:
- 查询全体学生的姓名及其年龄
select sname,(extract(year from current_date)-extract(year from sbirthdate)) '年龄'
from student;
'年龄’是通过指定别名来改变查询结果的列标题
extract(year from current_date)是kingbase提供的内置函数,不同DBMS提供的内置函数不同,所以在写sql语句时一定要参考所使用的产品手册
可以在select语句中加上说明含义的一个列标题:
- 查询全体学生的姓名、出生日期和主修专业
select sname,'date of birth:',sbirthdate,smajor
from student;
2.选择表中的若干元组
消除取值重复的行
两个本来并不完全相同的元组在投影到指定的某些列上后,可能会变成相同的行。可以用distinct消除它们:
- 查询选修了课程的学生学号
select sno from sc;
//等价于
select all sno from sc;
- 该查询结果里包含了许多重复的行。如想去掉结果表中的重复行,必须指定distinct:
select distinct sno from sc;
查询满足条件的元组
查询条件 | 谓词 |
---|---|
比较 | =, >, <, >=, <=, !=, <>, !>, !<; not+上述运算符 |
确定范围 | between and, not between and |
确定集合 | in, not in |
字符匹配 | like, not like |
空值 | is null, is not null |
多重条件(逻辑运算) | and, or, not |
比较大小:
- 查询主修计算机科学与技术专业全体学生的姓名
select sname from student
where smajor='计算机科学与技术';
- 查询2000年及2000年后出生的所有学生的姓名及其性别
select sname,ssex from student
where extract(year from sbirthdate) >= 2000;
- 查询考试成绩不及格的学生的学号
select distinct sno from sc
where grade < 60;
这里使用了distinct短语,当一个学生有多么课程不及格时,其学号也只列一次
确定范围:
- 查询年龄在20~23岁(包括20岁和23岁)之间的学生的姓名、出生日期和主修专业
select sname,sbirthdate,smajor from student
where extract(year from current_date) - extract(year from sbirthdate)
between 20 and 23;
- 查询年龄不在20~23岁范围内的学生的姓名、出生日期和主修专业
select sname,sbirthdate,smajor from student
where extract(year from current_date) - extract(year from sbirthdate)
not between 20 and 23;
确定集合:
谓词in可以用来查找属性值属于指定集合的元组
- 查询计算机科学与技术专业和信息安全专业的学生姓名及性别
select sname,ssex from student
where smajor in ('计算机科学与技术','信息安全');
相反,不属于则是not in
- 查询非计算机科学与技术专业和信息安全专业的学生姓名及性别
select sname,ssex from student
where smajor not in ('计算机科学与技术','信息安全');
字符匹配:
- 谓词like可以用来进行字符串的匹配,一般语法如下:
[not] like '匹配串' [escape '换码字符'];
即查找指定的属性列值与<匹配串>相匹配的元组
通配符的使用:
a.%代表任意长度的字符串。例如:a%b表示以a开头,b结尾的任意长度的字符串。如acb,addgb,ab等都满足该匹配串
b._代表任意单个字符。例如:"a_b"表示以a开头,以b结尾的长度为3的任意字符串,如acb, afb等都满足该匹配串
- 查询学号为20180003的学生的详细情况
select * from student
where sno like '20180003';
//等价于
select * from student
where sno='20180003';
//如果like后面的匹配串种不含通配符,则可以用=代替like,用!=或者<>运算符代替not like谓词
- 查询所有姓刘的学生的姓名、学号和性别
select sname,sno,ssex from student
where sname like '刘%';
- 查询2018级学生的学号和姓名
select sno,sname from student
where sno like '2018%'; //学号的数据类型是字符,用字符匹配
- 查询课程号为81开头,最后一位是6的课程名称和课程号
select cname,cno from course
where cno like '81__6'; //课程号为固定长度,占5个字符大小
- 查询所有不姓刘的学生的姓名、学号和性别
select sname,sno,ssex from student
where not like '刘%';
如果用户要查询的字符串本身就含有通配符%或_,这时就要使用escape’<换码字符>'短语对通配符进行转义了。
- 查询db_design课程的课程号和学分
select sno,credit from course
where cname like 'db\_design' escape '\';
”escape’'表示”\“为换码字符。这一匹配串中紧跟在”\“后面的字符”_“不再具有通配符的含义,转义为普通的 _ 字符“
- 查询以“db_”开头,且倒数第三个字符为i的课程的详细情况
select * from course
where cname like 'db\_%i__' escape '\';
//第一个_前有换码字符,所以被转义为普通的_字符。而i后的两个_的前面均没有换码字符,所以它们仍作为通配符
设计空值的查询
某些学生选修课程后没有参加考试,所以有选课记录但没有考试成绩。
- 查询缺少成绩的学生的学号和相应课程号。
select Sno,Cno
from sc
where grade is null;
//注意这里的“is”不能用“=”代替
- 查所有有成绩的学生的学号和选修的课程号
select sno,cno
from sc
where grade is not null;
多重条件的查询
逻辑运算符and和or可用来连接多个查询条件。and的优先级>or,但用户可以用括号改变优先级
- 查询主修计算机科学与技术专业,在2000年(包括2000年)以后出生的学生的学号、姓名和性别。
select sno,sname,ssex
from student
where smajor='计算机科学与技术专业' and extract(year from sbirthdate) >= 2000;
- 查询计算机科学与技术专业和信息安全专业的学生姓名及性别。in谓词实际上是多个or运算符的缩写,因此该例中的查询也可以用or运算符携程如下等价形式
select sname,ssex
from student
where smajor = '计算机科学与技术' or smajor = '信息安全';