查看: 421|回复: 0

[SQLServer] SQL数据查询之——单表查询

发表于 2018-1-8 08:00:02
一、SQL数据查询的一般格式

数据查询是数据库的核心操作。SQL提供了SELECT语句进行数据查询,其一般格式为:

  1. SELECT [ALL | DISTINCT]<目标列表达式>[,<目标列表达式>]···
  2. FROM<表名或视图名>[,<表名或视图名>···] | (SELECT语句>)[AS]<别名>
  3. [WHERE<条件表达式>]
  4. [GROUP BY<列名1>[HAVING<条件表达式>]]
  5. [ORDER BY<列名2>[ASC | DESC]];
复制代码

整个SELECT语句的含义是,根据WHERE子句的条件表达式从FROM子句指定的基本表、视图或派生表中找出满足条件的元组,再按SELECT子句中的目标列表达式选出元组中的属性值形成结果表

如果有GROUP BY子句,则将结果按<列名1>的值进行分组,该属性列值相等的元组为一个组。通常会在每组中作用聚集函数。如果GROUP BY子句带HAVING短语,则只有满足指定条件的组才予以输出。

如果有ORDER BY子句,则结果还要按<列名2>的值的升序或降序排序。

SELECT语句既可以完成简单的单表查询,也可以完成复杂的连接查询和嵌套查询。

二、SQL单表查询(仅涉及一个表的查询) 1.选择表中的若干列

(1)查询指定列

查询全体学生的学号与姓名

  1. SELECT Sno,Sname
  2. FROM Student;
复制代码

查询全体学生的姓名、学号、所在系

  1. SELECT Sname,Sno,Sdept
  2. FROM Student;
复制代码

(2)查询全部列

查询全体学生的详细记录

  1. SELECT *
  2. FROM Students;
  3. 等价于
  4. SELECT Sno,Sname,Ssex,Sage,Sdept
  5. FROM Student;
复制代码

(3)查询经过计算的值

查询全体学生的姓名及其出生年份

  1. SELECT Sname,2014-Sage //查询结果的第2列是一个 算术表达式
  2. FROM Student;
复制代码

注意:用当时的年份(假设为2014年)减去学生的年龄,这样所得的即是学生的出生年份。

查询全体学生的姓名、出生年份和所在的院系,要求用小写字母表示系名

  1. SELECT Sname,'Year of Birth:',2014-Sage,LOWER(Sdept)
  2. FROM Student;
复制代码

2.选择表中的若干组

(1)消除取值重复的行

查询选修了课程的学生学号

  1. SELECT DISTINCT Sno
  2. FROM SC;
复制代码

(2)查询满足条件的元组

查询满足指定条件的元组可以通过WHERE子句实现。WHERE子句常用的查询条件如下表所示

查询条件

谓词

比较

=,>,<,>=,<=,!=,<>,!>,!<; NOT+上述比较运算符

确定范围

BETWEEN AND,NOT BETWEEN AND

确定集合

IN,NOT IN

字符匹配

LIKE,NOT LIKE

空值

IS NULL,IS NOT NULL

多重条件(逻辑运算)

AND,OR,NOT

查询计算机科学系全体学生的名单

  1. SELECT Sname
  2. FROM Student
  3. WHERE Sdept='CS'
复制代码

查询所有年龄在20岁以下的学生姓名及其年龄

  1. SELECT Sname,Sage
  2. FROM Student
  3. WHERE Sage<20;
复制代码

查询考试成绩不合格的学生的学号

  1. SELECT DISTINCT Sno
  2. FROM SC
  3. WHERE Grade<60;
复制代码

查询年龄在20~23岁之间的学生的姓名、系别和年龄

  1. SELECT Sname,Sdept,Sage
  2. FROM Student
  3. WHERE Sage BETWEEN 20 AND 23
复制代码

查询年龄在20~23岁之间的学生的姓名、系别和年龄

  1. SELECT Sname,Sdept,Sage
  2. FROM Student
  3. WHERE Sage NOT BETWEEN 20 AND 23
复制代码

查询计算机科学系(CS)、数学系(MA)和信息系(IS)学生的姓名、系别和年龄

  1. SELECT Sname,Ssex
  2. FROM Student
  3. WHERE Sdept IN('CS','MA','IS');
复制代码

查询学号为201215121的学生的详细情况

  1. SELECT *
  2. FROM Student
  3. WHERE Sno LIKE '201215121'
  4. 等价于
  5. SELECT *
  6. FROM Student
  7. WHERE Sno='201215121'
复制代码

此处介绍下字符匹配

谓词LIKE可以用来进行字符串的匹配。其一般语法格式如下:

  1. [NOT] LIKE'<匹配串>' [ESCAPE '<换码字符>']
复制代码

其含义是查找指定的属性列值与<匹配串>相匹配的元组。<匹配串>可以是一个完整的字符串,也可以含有通配符 % 和 _ 。其中:

  • %(百分号)代表任意长度(长度可以为0)的字符串。例如:a%b 表示以a开头,以b结尾的任意长度的字符串。如acb、addgb、ab等。
  • _(下划线)代表任意单个字符。例如:a_b表示以a开头,以b结尾的长度为3的任意字符串。如acb、agb等。

查询所有姓刘的学生的姓名、学号和性别

  1. SELECT Sname,Sno,Ssex
  2. FROM Student
  3. WHERE Sname LIKE '刘%';
复制代码

查询姓“欧阳”且全名为三个汉字的学生的姓名

  1. SELECT Sname
  2. FROM Student
  3. WHERE Sname LIKE '欧阳_'
复制代码

注意:数据库字集为ASCII时一个汉字需要两个_;当字符集为GBK时只需要一个。

查询名字中第二个字为“阳”的学生的姓名和学号

  1. SELECT Sname,Sno,
  2. FROM Student
  3. WHERE Sname LIKE '_阳%';
复制代码

查询所有不姓刘的学生的姓名、学号和性别

  1. SELECT Sname,Sno,Ssex
  2. FROM Student
  3. WHERE Sname NOT LIKE '刘%';
复制代码

如果用户要查询的字符串本身就含有通配符%或_,这时就要使用 ESCAPE '<换码字符>' 短语对通配符进行转义了。

查询DB_Design 课程的课程号和学分

  1. SELECT Cno,Ccredit
  2. FROM Course
  3. WHERE Cname LIKE 'DB \ _Design' ESCAPE '\';
复制代码

ESCAPE '\' 表示 “\” 为换码字符。这样匹配串中紧跟在 “\” 后面的字符“_”不再具有通配符的含义,转义为普通的“_”字符。

查询以“DB_”开头,且倒数第三个字符为i的课程的详细情况

  1. SELECT *
  2. FROM Course
  3. WHERE Cname LIKE 'DB \_%i__'ESCAPE '\';
复制代码

某些学生选修课程后没有参加考试,所以有选课记录,但没有考试成绩。查询缺少成绩的学生的学号和相应的课程号

  1. SELECT Sno,Cno
  2. FROM SC
  3. WHERE Grade IS NULL; /*分数Grade是空值*/
复制代码

注意:这里的“IS”不能用等号(=)代替。

查所有有成绩的学生学号和课程号

  1. SELECT Sno,Cno
  2. FROM SC
  3. WHERE Grade IS NOT NULL;
复制代码

查询计算机科学系年龄在20岁以下的学生姓名

  1. SELECT Sname
  2. FROM Student
  3. WHERE Sdept='CS' AND Sage<20;<br />
复制代码

3.ORDER BY 子句

用户可以用ORDER BY子句对查询结果按照一个或多个属性列的升序(ASC)或降序(DESC)排列,默认值为升序。

查询选修了3号课程的学生的学号及其成绩,查询结果按分数的降序排列

  1. SELECT Sno,Grade
  2. FROM SC
  3. WHERE Cno='3'
  4. ORDER BY Grade DESC;
复制代码

查询全体学生情况,查询结果按所在系的系号升序排列,同一系中的学生按年龄降序排列

  1. SELECT *
  2. FROM Student
  3. ORDER BY Sdept,Sage DESC;
复制代码

4. 聚集函数

为了进一步方便用户,增强检索功能,SQL提供了许多聚集函数,主要有:

COUNT(*)

统计元组个数

COUNT([DISTINCT|ALL]<列名>)

统计一列中值的个数

SUM([DISTINCT|ALL]<列名>)

计算一列值的总和(此列必须是数值型)

AVG([DISTINCT|ALL]<列名>)

计算一列值的平均值(此列必须是数值型)

MAX([DISTINCT|ALL]<列名>)

求一列值中的最大值

MIN([DISTINCT|ALL]<列名>)

求一列值中的最小值

如果指定 DISTINCT 短语,则表示在计算时要取消指定列中的重复值。

如果不指定 DISTINCT 短语或指定 ALL 短语(ALL为默认值),则表示不取消重复值。

查询学生总人数

  1. SELECT COUNT(*)
  2. FROM Student;
复制代码

查询选修了课程的学生人数

  1. SELECT COUNT(DISTINCT Sno)
  2. FROM SC;
复制代码

计算选修1号课程的学生平均成绩

  1. SELECT AVG(Grade)
  2. FROM SC
  3. WHERE Cno='1';
复制代码

查询选修1号课程的学生最高分数

  1. SELECT MAX(Grade)
  2. FROM SC
  3. WHERE Cno='1';
复制代码

查询学生201215012选修课程的总学分数

  1. SELECT SUM(Ccredit)
  2. FROM SC,Course
  3. WHERE Sno='201215012' AND SC.Cno=Course.Cno;
复制代码

注意:WHERE 子句中是不能用聚集函数作为条件表达式的。聚集函数只能用于SELECT子句和GROUP BY中的HAVING子句。

5.GROUP BY子句

将查询结果按某一列或多列的值分组,值相等的为一组。

求各个课程号及相应的选课人数

  1. SELECT Cno,COUNT(Sno)
  2. FROM SC
  3. GROUP BY Cno;
复制代码

查询选修了三门以上课程的学生学号

  1. SELECT Sno
  2. FROM SC
  3. GROUP BY Sno
  4. HAVING COUNT(*)>3;
复制代码

查询平均成绩大于等于90分的学生学号和平均成绩

  1. SELECT Sno,AVG(Grade)
  2. FROM SC
  3. WHERE AVG(Grade)>=90 (错误!)
  4. GROUP BY Sno;
  5. 因为WHERE子句中是不能用聚集函数作为条件表达式的,正确的查询语句应该是:
  6. SELECT Sno,AVG(Grade)
  7. FROM SC
  8. GROUP BY Sno;
  9. HAVING AVG(Grade)>=90;
复制代码

三、总结

此次整理了SQL数据查询中有关单表查询的程序,其中应格外注意

  • 字符匹配中 % 和 _ 的区别。
  • ESCAPE 的 换码操作。
  • 聚集函数只能用于 SELECT子句 和 GROUP BY子句 中的 HAVING 子句。



回复

使用道具 举报