LAMP网站开发黄金组合Linux+Apache+MySQL+PHP
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

4.5 简单的SQL查询语言

SQL查询语句的格式如下:

    SELECT[ALL | DISTINCT]<目标列表达式>[,<目标列表达式>]…
    FROM<表名或视图名>[,<表名或视图名>]…
    [WHERE<条件表达式>]
    [GROUP BY<列名1>[HAVING <条件表达式>]]
    [ORDER BY<列名2>[ASC | DESC]];

查询语句可以分为SELECT子句、FROM子句、WHERE子句、GROUP BY子句和ORDER BY子句。

SELECT子句指明需要查询的项目,一般是列名,也可以是表达式。利用表达式,可以查询表中并未存储但可以导出的结果。FROM子句指明被查询的表或视图名。如果需要,也可以为表和视图取一别名,这种别名只在本句中有效。SELECT子句和FROM子句是每个SQL查询语句所必需的,其他子句是任选的。WHERE子句说明查询的条件。GROUP BY子句用来将结果分组。ORDER BY子句将结果排序。

查询语句可以完成简单的单表查询,也可以完成复杂的多表查询和嵌套查询。本节主要介绍在最常用的查询中各个子句如何使用。在下一节会介绍比较复杂的联合查询。

为了便于举例,在这里先给出后面例子中用到的表。假设数据库中有三个表:STUDENTS表、COURSE表和SC(学生选课)表,分别如表4-3、表4-4、表4-5所示。

表4-3 STUDENTS表

表4-4 COURSE表

表4-5 SC表(学生选课表)

★ 注意 ★

“ ?”表示该元组的该字段为空。

4.5.1 SELECT子句和FROM子句

SELECT子句指明需要查询的项目,FROM子句指明被查询的表或视图名。SELECT子句和FROM子句可以构成最基本的查询语句。例如,需要查询全体学生的学号和系别,SQL查询语句如下:

    SELECT SNO,SDEPT FROM STUDENTS;

若要查询表的全部列,则可以将<目标列表达式>指定为*。例如要查询课程的详细记录,SQL查询语句如下:

    SELECT * FROM COURSE;

前面提到过,SELECT子句后面的<目标列表达式>可以是列名,也可以是表达式,例如查询学生的姓名和出生年份。假设今天是2005年,那么由SAGE字段值就可以得到出生年份。SQL语句如下:

    SELECT SNAME,2005-SAGE FROM STUDENTS;

可以看到第二个<目标列表达式>就是一个计算表达式。

在SELECT子句中有DISTINCT选项,在使用查询语句时,满足条件的结果可能不止一个,如果加了DISTINCT选项,则要求消除查询结果中的重复项。例如,查询选课表中的课程号,不要重复字段,SQL语句如下:

    SELECT DISTINCT CNO FROM SC;

结果如下表4-6所示。

表4-6 查询结果表

如果没有指定DISTINCT选型,则默认为ALL选项,就会保留所有结果。

4.5.2 WHERE子句定义查询条件

前面的例子都是查询表中所有行的数据,只是对列进行了查询,也就是投影操作,而更普遍的应用是使用WHERE子句定义查询条件,在投影操作的同时也进行元组的选择。

WHERE子句后面加条件表达式。常用的查询条件如表4-7所示。

表4-7 常用的查询条件

下面分别介绍各类查询符号的用法。

1.比较

SQL语言中的比较符号和数学中的比较符号是统一的,这也是SQL语言易懂易学的原因。表4-7的第一行给出了所有比较符号,其中NOT加上比较运算符表示对条件求非。

例如需要查询STUDENTS表中,年龄大于20岁的学生的姓名和系别,SQL语句如下:

    SELECT SNAME,SDEPT FROM STUDENTS WHERE SAGE>20;

2.确定范围

BETWEEN条件可表示为E [NOT] BETWEEN E1 AND E2,其语义可以用比较符号表示为[NOT](E>=E1 AND E<=E2)。其中AND是多重条件符号。

例如查询学生选课表(SC)中,成绩在80分到90分之间(包括80和90分)的学生的学号和成绩。SQL语句如下:

    SELECT SNO,GRADE FROM SC WHERE GRADE BETWEEN 80 AND 90;

3.确定集合

IN条件可以表示为E [NOT] IN(V1,V2,…,Vn),其语义相当于[NOT] (E=V1 OR E=V2 OR…OR E=Vn),也就是说查找属性值属于指定集合(V1,V2,…,Vn)的元组。

例如查询学生表中数学系和英语系学生的姓名和系别,SQL语句可以如下表达:

    SELECT SNAME,SDEPT FROM STUDENTS WHERE SDEPT IN('English','Maths');

4.字符匹配

LIKE条件用于字符串的比较,在比较时,引用了两个具有特殊意义的通配符:下画线“_”和百分号“%”。

● 下画线“_”表示任意单字符;

● 百分号“%”表示包括长为零的任意长的字符串。

LIKE条件可以表示为E [NOT] LIKE ‘<匹配串>’,其中匹配串中可以是一个完整的字符串,也可以是包含通配符的字符串。

★ 说明 ★

如果是完整的字符串,则可以使用比较符号的等号“=”取代LIKE。

例如查询课程号为“C001”的详细情况,SQL语句如下:

    SELECT * FROM COURSE WHERE CNO LIKE 'C001';

其实该语句就等价与

    SELECT * FROM COURSE WHERE CNO='C001';

例如查询姓李的学生的详细信息,SQL语句如下:

    SELECT * FROM STUDENTS WHERE SNAME LIKE '李%';

★ 注意 ★

在使用下画线“_”代表字符时,一个汉字应该使用两个下画线,因为一个汉字占两个字符的位置。

5.涉及NULL的查询

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

    SELECT SNO,CNO FROM SC WHERE GRADE IS NULL;

6.多重条件查询

AND和OR可以用来联结多个查询条件。例如,查询学生表中年龄大于20的男学生的详细信息,SQL语句如下:

    SELECT * FROM STUDENTS WHERE SAGE>20 AND SSEX='男';

4.5.3 GROUP BY子句对查询结果分组

GROUP BY子句将表按列的值分组,列的值相同的分为一组。如果GROUP BY后面有多个列名,则先按第一列名分组,再在每组中按第二列名分组。GROUP BY子句经常与聚集函数联用,所以下面会先简单介绍聚集函数。如果分组后还要求按一定的条件对组进行筛选,最终只输出满足条件的组,则可以使用HAVING子句。

SQL中的聚集函数有AVG、MAX、MIN、SUM、COUNT五种。聚集函数的变量为一集合。AVG表示取平均值。MAX/MIN表示取最大值或最小值。SUM表示求和。COUNT表示元组个数。

在使用聚集函数时,若不使用GROUP BY子句,则作用于整个查询结果。例如,查询选课学生的平均分,SQL语句如下;

    SELECT AVG(GRADE) FROM SC;

而如果在GROUP BY子句中使用聚集函数,则分组后,聚集函数会作用于每个组,每个组都得到一个函数值。

例如求各门选课的平均成绩,SQL语句如下,结果如表4-8所示。

表4-8 查询结果表

    SELECT CNO,AVG(GRADE) FROM SC GROUP BY CNO;

4.5.4 ORDER BY子句对查询结果分组

ORDER BY子句可对查询结果按子句中指定的列的值排序。列可以用列名表示,也可以用在SELECT子句中出现的序号表示。后者书写起来比较简便,特别当选择的列是聚集函数或表达式时,由于没有列名,只能用序号表示。ASC选项表示升序,DESC选项表示降序,默认时表示升序。

例如,查询学生选课表,给出选了C001号课程的学生的学号和成绩,结果以成绩升序排列。SQL语句如下:

    SELECT SNO,GRADE FROM SC WHERE CNO='C001' ORDER BY GRADE ASC;