5.1 简单查询

在MySQL中可以通过SQL语句来实现基本数据查询,SQL语句可以通过如下几种方式使用:查询所有字段数据、查询指定字段数据、避免重复数据查询、实现数学四则运算数据查询、设置显示格式数据查询。

数据库中可能包含无数的表,表中可能包含无数的记录,因此要获得所需的数据并非易事。在MySQL中,可以使用SELECT语句来查询数据,根据查询条件的不同,数据库系统会找到不同的数据,通过SELECT语句可以很方便地获取所需的信息。

在MySQL中,SELECT语句的基本语法形式如下:

       SELECT field1 field2 … fieldn
    FROM tablename
    [WHERE CONDITION1]
    [GROUP BY fieldm [HAVING CONDITION2]]
    [ORDER BY fieldn [ASC|DESC]]

其中,filed1~fieldn参数表示需要查询的字段名;tablename参数表示表的名称;CONDITION1参数表示查询条件;fieldm参数表示按该字段中的数据进行分组;CONDITION2参数表示满足该表达式的数据才能输出;fieldn参数指按该字段中数据进行排序。排序方式由ASC和DESC两个参数指出;ASC参数表示按升序的顺序进行排序,是默认参数;DESC参数表示按降序的顺序进行排序。

5.1.1 查询所有字段数据

查询所有字段是指查询表中所有字段的数据,这种方式可以将表中所有字段的数据都查询出来。MySQL有两种方式可以查询表中的所有字段。

1. 列出表的所有字段

通过SQL语句SELECT列出表的所有字段,具体语法形式如下:

    SELECT field1,field2,…,fieldn FROM tablename;

其中,filed1~fieldn参数表示需要查询的字段名;tablename参数表示表的名称。

2. “*”符号的使用

查询所有字段数据,除了使用上面的方式外,还可以通过符号“*”来实现,具体语法形式如下:

    SELECT * FROM tablename;

其中,符号“*”表示所有字段名;tablename参数表示表的名称。

与上一种方式相比,“*”符号方式的优势比较明显,即可用该符号代替表中的所有字段,但是这种方式不够灵活,只能按照表中字段的固定顺序显示,不能随便改变字段的顺序。

5.1.2 查询指定字段数据

查询所有字段数据,需要在关键字SELECT后指定包含所有字段的列表或者符号“*”;如果需要查询指定字段数据,只需修改关键字SELECT后的字段列表为指定字段即可。

例如,从学生表中查询姓名、性别和年龄字段,SQL语句如下所示。

    SELECT name,gender,age FROM t_student;

如果关键字SELECT后面的字段不包含在所查询的表中,那么MySQL会报错。

5.1.3 DISTINCT查询

当在MySQL中执行简单数据查询时,有时会显示出重复数据。为了实现查询不重复数据,MySQL提供了DISTINCT功能,SQL语法如下:

在上述语句中,关键字DISTINCT去除重复的数据。下面将通过一个具体的示例来说明如何实现查询不重复数据。

【示例5-1】执行SQL语句SELECT,在数据库school中查询学生表t_student中age字段的数据。具体步骤如下:

(1)使用如下SQL语句在学生表中查询数据,执行结果如图5-1所示。

    SELECT age FROM t_student;

(2)为了避免查询到重复的数据,可以执行SQL语句关键字DISTINCT,具体SQL语句如下,执行结果如图5-2所示。

    SELECT DISTINCT age FROM t_student;

在上述语句中,通过关键字DISTINCT修饰关键字SELECT后面的字段age,以避免查询到重复的数据记录。

图5-1 查询学生表数据记录

图5-2 查询学生表不重复数据记录

图5-1所示的执行结果显示,查询到字段age有重复的数据;图5-2所示的执行结果显示,与图5-1相比,关键字DISTINCT去除了重复的数据。

5.1.4 IN查询

在MySQL中提供了关键字IN,用来实现判断字段的数值是否在指定集合的条件查询,该关键字的具体语句形式如下:

    SELECT field1,field2,…,fieldn
    FROM tablename WHERE filedm IN(value1,value2,value3,…,valuen);

在上述语句中,参数fieldn表示名称为tablename的表中的字段名,参数valuen表示集合中的值,通过关键字IN来判断字段fieldm的值是否在集合(value1,value2,value3,…,valuen)中,如果字段fieldm的值在集合中,就满足查询条件,该记录会被查询出来,否则不会被查询出来。

1. 在集合中的数据记录查询

下面通过一个具体的示例来说明如何实现在集合中的数据记录查询。

【示例5-2】执行SQL语句SELECT,在数据库school的学生成绩表s_score中查询学生编号为1001、1004、1009、1010的学生。

执行SQL语句SELECT,通过关键字IN设置集合查询条件,以实现查询学生编号为1001、1004、1009和1010的学生数据记录,具体SQL如下,执行结果如图5-3所示。

    SELECT name FROM s_score WHERE stuid IN(1001,1004,1009,1010);

图5-3 查询数据表记录

2. 不在集合中的数据记录查询

通过关键字NOT IN设置集合查询条件,以实现查询学生编号不为1001、1004、1009、1010的学生,具体SQL语句如下:

    SELECT name FROM s_score
    WHERE stuid NOT IN(1001,1004,1009,1010);
3. 集合查询的注意点

在具体使用关键字IN时,查询的集合中如果存在NULL,则不会影响查询;使用关键字NOT IN,查询的集合中如果存在NULL,则不会有任何的查询结果。

【示例5-3】执行SQL语句SELECT,在数据库school的学生成绩表s_score中查询学生编号为1001、1004、1009、1010的学生。具体操作如下:

(1)执行SQL语句SELECT,通过关键字IN设置集合查询条件,以实现查询学生编号为1001、1004、1009、1010的学生,集合里包含NULL,具体SQL语句如下,执行结果与图5-3一致。

    SELECT name FROM s_score
    WHERE stuid IN(1001,1004,1009,1010,NULL);

(2)通过关键字NOT IN设置集合查询条件,以实现查询学生编号不为1001、1004、1009、1010的学生,关键字NOT IN所操作的集合中包含了NULL值,具体SQL语句如下,执行结果如图5-4所示。

    SELECT name FROM s_score
    WHERE stuid NOT IN(1001,1004,1009,1010,NULL);

图5-4 查询数据信息

5.1.5 BETWEEN AND查询

MySQL提供了关键字BETWEEN AND,用来实现判断字段的数值是否在指定范围内的条件查询。该关键字的具体语法形式如下:

    SELECT field1,field2,…,fieldn
    FROM tablename WHERE fieldm BETWEEN minvalue AND maxvalue

在上述语句中,参数fieldn表示名称为tablename的表中的字段名,通过关键字BETWEEN和AND来设置字段field的取值范围,如果字段field的值在所指定的范围内,那么满足查询条件,该记录会被查询出来,否则不会被查询出来。

BETWEEN minvalue AND maxvalue,表示的是一个范围间的判断过程,只针对数字类型。

1. 符合范围的数据记录查询

通过关键字BETWEEN和AND设置查询范围,以实现查询语文成绩(字段Chinese)在85和90之间的学生,具体SQL如下:

    SELECT name,Chinese
    FROM s_score WHERE Chinese BETWEEN 85 AND 90;
2. 不符合范围的数据记录查询

通过关键字NOT设置非查询范围条件,具体SQL语句如下:

    SELECT name,Chinese
    FROM s_score WHERE Chinese NOT BETWEEN 85 AND 90;

5.1.6 LIKE模糊查询

MySQL提供了关键字LIKE来实现模糊查询,具体语法形式如下:

    SELECT field1,field2,…,fieldn
    FROM tablename WHERE fieldm LIKE value;

在上述语句中,参数tablename表示表名,参数fieldn表示表中的字段名字,通过关键字LIKE来判断字段field的值是否与value字符串匹配,如果相匹配,则满足查询条件,该记录就会被查询出来;否则就不会被查询出来。

在MySQL中,字符串必须加上单引号('')和双引号(″″)。由于关键字LIKE可以实现模糊查询,因此该关键字后面的字符串参数除了可以使用完整的字符串外,还可以包含通配符。LIKE关键字支持的通配符如表5-1所示。

表5-1 LIKE关键字支持的通配符

1. 带有“%”通配符的查询

(1)查询字段name中以字母L开头的数据记录,具体SQL语句如下:

    SELECT name FROM s_score WHERE name LIKE 'L%';

(2)MySQL不区别大小写,上述SQL语句可以修改如下:

    SELECT name FROM s_score WHERE name LIKE 'j%';

(3)如果想查询不是以字母L开头的全部学生,可以执行逻辑非运算符(NOT或!),具体SQL语句如下:

    SELECT name FROM s_score WHERE NOT name LIKE 'j%';
2. 带有“_”通配符的查询

(1)查询字段name中以第二个字母为A的数据记录,具体SQL语句如下:

    SELECT name FROM s_score WHERE name LIKE '_A%';

(2)如果想查询第二个字母不是A的全部学生,可以执行逻辑非运算符(NOT或!),具体SQL语句如下:

    SELECT name FROM s_score WHERE NOT name LIKE '_A%';

(3)如果想查询第二个字母不是A的全部学生,也可以用以下SQL语句查询:

    SELECT name FROM s_score WHERE name NOT LIKE '_A%';
3. 使用LIKE关键字查询其他类型数据

在MySQL中,LIKE关键字除了可以操作字符串类型的数据外,还可以操作其他任意的数据类型。

(1)执行SQL语句SELECT,查询字段English带有数字9的全部学生,具体SQL语句如下:

    SELECT name,English FROM s_score WHERE English LIKE '%9%';

(2)对于LIKE关键字,如果匹配“%%”,就表示查询所有数据记录。

    SELECT name FROM s_score WHERE name LIKE '%%';

5.1.7 对查询结果排序

在MySQL中,从表中查询出的数据可能是无序的,或者其排列顺序不是用户所期望的顺序,为了使查询结果的顺序满足用户的要求,可以使用关键字ORDER BY对记录进行排序,其语法形式如下:

    SELECT field1, field2, field3, …, fieldn
    FROM tablename ORDER BY fieldm [ASC|DESC]

在上述语句中,参数tablename表示所要进行排序的表名,参数fieldn表示表中的字段名字,参数fieldm表示按照该字段进行排序;ASC表示按升序进行排序;DESC表示按降序进行排序。默认的情况下按ASC进行排序。

(1)执行SQL语句SELECT,查询表s_score中所有的数据记录,按照语文成绩(字段Chinese)升序排序,具体SQL语句如下:

    SELECT stuid,name,Chinese FROM s_score ORDER BY Chinese ASC;

(2)执行SQL语句SELECT,查询表s_score中所有的数据记录,按照语文成绩(字段Chinese)降序排序,具体SQL语句如下:

    SELECT stuid,name,Chinese FROM s_score ORDER BY Chinese DESC;

提示

如果存在一条记录字段的值为空值(NULL),那么按升序排序时,含空值的记录将最先显示,可以理解为空值是该字段的最小值;按降序排列时,字段为空值的记录将最后显示。

在MySQL中,可以指定多个字段进行排序。例如,可以让表s_score先按照字段Chinese升序排序,再按照字段English降序排序,具体SQL语句如下:

5.1.8 简单分组查询

MySQL软件提供了5个统计函数来帮助用户统计数据,可以使用户很方便地对记录进行统计数、计算和、计算平均数、计算最大值和最小值,而不需要查询所有数据。

在具体使用统计函数时,都是针对表中所有记录数或指定特定条件(WHERE子句)的数据记录进行统计计算。在现实应用中,经常会先把所有数据记录进行分组,再对这些分组后的数据记录进行统计计算。

MySQL通过SQL语句GROUP BY来实现,分组数据查询语法如下:

    SELECT function()
    FROM tablename WHERE CONDITION GROUP BY field;

在上述语句中,参数field表示某字段名,通过该字段对名称为tablename的表的数据记录进行分组。

提示

在具体进行分组查询时,分组所依据的字段上的值一定要具有重复值,否则分组没有任何意义。

【示例5-4】使用SQL语句GROUP BY对所有数据记录按不同字段进行分组。

(1)执行SQL语句GROUP BY,对所有数据记录按学科(字段subject)进行分组,具体SQL语句如下,执行结果如图5-5所示。

    SELECT * FROM s_teacher GROUP BY subject;

(2)关于关键字GROUP BY,如果所针对的字段没有重复值,那么分组没有任何意义。比如按照教师编号tid进行分组,具体SQL语句如下,执行结果如图5-6所示。

    SELECT * FROM s_teacher GROUP BY tid;

图5-5 查看表数据

图5-6 查看表数据

图5-5已经根据字段subject将表s_teacher进行分组,然后显示每组中的一条数据。

图5-6显示表s_teacher的所有数据记录,由于数据库school的表s_teacher中字段tid的值没有重复值,所以首先将每一条记录分成一组,然后显示每组中的一条记录。该分组查询与没有分组查询的结果是一样的,所以没有任何实际意义。

5.1.9 统计分组查询

在MySQL中,只实现简单的分组查询是没有任何实际意义的,因为关键字GROUP BY单独使用时,默认查询出每个分组中随机的一条记录,具有很大的不确定性,一般建议将分组关键字与统计函数一起使用。

如果想显示每个分组中的字段,可以通过函数GROUP_CONCAT()来实现。该函数可以实现显示每个分组中的指定字段,函数的具体语法形式如下:

    SELECT GROUP_CONCAT(field)
    FROM tablename
    WHERE CONDITION GROUP BY field;

在上述语句中会显示每个数组中的字段值。

【示例5-5】使用GROUP_CONCAT()对教师进行统计分组,并显示每组人数。

(1)执行SQL语句GROUP_CONCAT(),显示每个分组,具体SQL语句如下:

    SELECT subject,GROUP_CONCAT(name) name
    FROM s_teacher GROUP BY subject;

(2)执行统计函数COUNT(),显示每个分组中教师的个数,具体SQL语句如下:

    SELECT subject,GROUP_CONCAT(name) name,COUNT(name) number
    FROM s_teacher GROUP BY subject;