SQLSERVER的查询操作
3.4单表的数据查询
创建一个基本表,如下:
create table Student
(
s_no char(6) primary key,
class_no char(6) not null,
s_name varchar(10) not null,
s_sex char(2) check(s_sex = '男' or s_sex = '女'),
s_birthday datetime
)
| s_no | class_no | s_name | s_sex | s_birthday99120 |
|---|---|---|---|---|
| 991201 | js0001 | 徐辉 | 女 | 1978-08-01 00:00:00.000 |
| 991101 | js0002 | 王一山 | 男 | 1980-12-04 00:00:00.000 |
| 991104 | js0002 | 牛莉 | 女 | 1981-06-09 00:00:00.000 |
| 002101 | xx0001 | 李丽丽 | 女 | 1981-09-19 00:00:00.000 |
| 991102 | xx0001 | 李王 | 男 | 1980-09-23 00:00:00.000 |
3.4.1无条件查询
格式为:select 列名 from 表名
select s_no,class_no,s_name,s_sex,s_birthday
from Student
或
select *
from Student
用 * 表示Student表的全部列名,而不必逐一列出
select distinct s_no,class_no as c_s
from Student
distinct 会消去重复行;as可以为查询结果的列名重新命名
3.4.2条件查询
格式为:select 列名 from 表名 where 条件
以下是条件查询中常用的几种比较运算符
比较大小(包含=、>=、<=、<、>、<>、!=)
//查询出生日期在1980年以后的学生的学号
select s_no
from Student
where s_birthday > '1980-01-01'
//查询所有男同学,要求显示其学号s_no、姓名s_name、出生日期s_birthday
select s_no,s_name,s_birthday
from Student
where s_sex = '男'
多重条件(包含AND、OR、NOT)
//查询所有出生日期在“1980-01-01”前的女同学,要求显示其学号s_no、姓名s_name、性别s_sex
select s_no,s_name,s_sex
from Student
where s_birthday < '1980-01-01' and s_sex = '女'
确定范围(BETWEEN…AND)
//查询出生日期在1980-1-1和1982-1-1之间的学生的姓名和出生日期
select s_name,s_birthday
from Student
where s_birthday between '1980-1-1' and '1982-1-1'
确定集合(IN)
//查询班号为js0001和js0002的学生的姓名和班号
select s_name,class_no
from Student
where class_no in('js0001','js0002')
此语句也可用OR实现
select s_name,class_no
from Student
where class_no = 'js0001' or class_no = 'js0002'
字符匹配(LIKE)
//查询所有姓“李”的男同学,要求显示其学号s_no、姓名s_name、性别s_sex、出生日期s_birthday
select s_no,s_name,s_sex,s_birthday
from Student
where s_sex = '男' and s_name like '李%'
//查询所有姓名中含有“一”字的同学,要求显示其学号s_no、姓名s_name。
select s_no,s_name
from Student
where s_name like '%一%'
%代表0个或多个字符;
_(下划线)代表一个字符
空值(IS NULL)
//查询出生日期为空的学生姓名
select s_name
from Student
where s_birthday is null
is null不能写成= null
3.4.3常用聚合函数
AVG(按列计算平均值)、SUM(按列计算值的总和)、MAX(求一列中的最大值)、MIN(求一列中的最小值)、COUNT(按列值统计个数)、COUNT(*)用来统计元组的个数,不消除重复行。
//查询有多少个班级
select count(distinct class_no) as classnum
from Student
distinct 表示消除重复行,as为查询的每一项内容取一个别名,否则查询结果中就不显示列名
3.4.4分组查询
GROUP BY子句可以将查询结果按属性列或属性列组合在行的方向上进行分组,每组在属性列或属性列组合上具有相同的值。
HAVING子句和WHERE子句一样是条件筛选,不同的是,WHERE子句是作用于基本表或视图,选出满足条件的元组,而HAVING子句是作用于组,选择满足条件的组。其顺序是WHERE 、GROUP BY、HAVING。
select count(s_no) as s_num
from Student
group by class_no
having(count(s_no) >= 2)
3.4.5查询结果的排序
ORDER BY子句可以为查询结果排序,DESC为降序,ASC为升序,默认时为升序。
select s_no
from Student
order by s_no asc
3.5多表的连接查询
inner join(内连接):显示符合条件的记录。
left outer join(左外连接):显示符合条件的数据行以及左边表中不符合条件的数据行,此时右边数据行以NULL显示。
right outer join(右外连接):显示符合条件的数据行以及右边表中不符合条件的数据行,此时左边数据行以NULL显示。
full outer join(全外连接):显示符合条件的数据行以及左边表和右边表中不符合条件的数据行,此时缺乏数据的数据行会以NULL显示。
cross join(交叉查询):将一个表中的每一个记录和另一个表中的每个记录匹配成新的数据行。
创建一个数据表如下:
create table Choice
(
s_no char(6),
course_no char(5),
score numeric(6,1)
)
| s_no | course_no | score |
|---|---|---|
| 991104 | 01001 | 78.0 |
| 991201 | 01001 | 67.0 |
| 991101 | 01002 | 90.0 |
| 991102 | 01002 | 58.0 |
3.5.1内连接查询
//查询所有同学的选课及成绩情况,要求显示学生的学号s_no,姓名s_name,课程号course_no和课程的成绩score
//隐式内连接查询
select Student.s_no,s_name,course_no,score
from Student,Choice
where Student.s_no = Choice.s_no
//显示内连接查询
select Student.s_no,s_name,course_no,score
from Student inner join Choice
on Student.s_no = Choice.s_no
3.5.2外连接查询
外部链接分为左外部连接和右外部连接两种。以主表所在的方向区分外部链接,主表在左边,则为左外部连接;主表在右边,则为右外部连接。
//查询所有同学情况,要求显示学生的学号s_no,姓名s_name,成绩score
select Student.s_no,s_name,score
from Student left outer join Choice
on Student.s_no = Choice.s_no
3.5.3交叉查询
select *
from Student cross join Choice
3.6子查询
3.6.1普通子查询
先执行子查询,然后把子查询的结果作为父查询的查询条件的值。
返回一个值的普通子查询
当子查询的返回值只有一个时,可以使用比较运算符(= 、>、<、!=、>=、<=)将父查询和子查询连接起来。
//查询和王一山是同一班级的同学的姓名(使用子查询)
select s_name
from Student
where class_no = (select class_no
from Student
where s_name = '王一山')
返回一组值的普通子查询
当子查询的返回值不是一个值,而是一组值的时候,不能用比较运算符,而应使用ANY或ALL或IN。
//查询教授课程号为01001的教师姓名
select s_name
from Student
where s_no = any( select s_no
from Choice
where course_no = '01001')
= ANY等价与IN;
NOT IN等价于<>ALL;
ALL等价于>MAX( ); < ALL等价于< MIN( );
ANY登记于>MIN( );
< ANY等价于 < MAX( )。
3.6.2相关子查询
首先选取父查询表中的第一行记录,内部的子查询利用此行中相关的属性值进行查询,然后父查询根据子查询返回的结果判断此行是否满足查询条件。如果满足条件,则把该行放入父查询的查询结果集合中.