码迷,mamicode.com
首页 > 其他好文 > 详细

查询数据

时间:2016-02-26 16:53:07      阅读:133      评论:0      收藏:0      [点我收藏+]

标签:

查询数据指从数据库中获取所需要的数据。查询数据是数据库操作中最常用,也是最重要操作。用户可能根据自己对数据的需求,使用不同的查询方式。通过不同的查询方式,可以获得不同的数据。MySQL中是使用SELECT语句来查询数据的。

- 查询语句的基本语法
- 在单表上查询数据
- 使用聚合函数查询数据
- 多表上联合查询
- 子查询
- 合并查询结果
- 为表和字段取别名
- 使用正则表达式查询
10.1 基本查询语句
查询数据是数据库操作中最常用的操作。通过对数据库的查询,用户可以从数据库中获取需要的数据。数据库中可能包含着无数的表,表中可能包含着无数记录。因此,要获得所需的数据并非易事。MySQL中可以使用SELECT语句来查询数据。根据查询的条件的不同,数据库系统会找到不同的数据。通过SELECT语句可以很方便的获取所需的信息。
 
MySQL中,SLEECT的基本语法形式如下:
 
SELECT 属性列表
FROM 表名和视图列表
[WHERE 条件表达式1]
[GROUP BY 属性名1] [HAVING 条件表达式2]
[ORDER BY 属性名[ASC|DESC]]
 
‘属性列表‘参数表示需要查询的字段名;
‘表名或视图列表‘参数表示此处指定的表或者视图中查询数据,表和视图可以有多个;
‘条件表达式1‘参数指定查询条件;
‘属性名1‘参数指按该字段中的数据进行分组;
‘条件表达式2‘参数表示满足该表达式的数据才能输出;
‘属性名2‘参数指按该字段中的数据进行排序,排序方式由‘ASC‘和‘DESC‘两个参数指出;
‘ASC‘参数表示按升序的顺序进行排序,这是默认排序;(从小到大)
‘DESC‘参数表示按降序的顺序进行排序。(从大到小)
 
如果有WHERE子句,就按照‘条件表达式1‘指定的条件进行查询。如果没有WHERE子句,就查询所有记录。
 
如果有GROUP BY子句,就按照‘属性名1‘指定的字段进行分组。如果GROUP BY子句后带着HAVING关键字,那么只有满足‘条件表达式2‘中指定的条件才能够输出。
GROUP BY子句通常和COUNT()、SUM()等聚合函数一起使用。
 
如果有ORDER BY子句,就按照‘属性名2‘指定的字段进行排序。排序方式由‘ASC‘和‘DESC‘两个参数指出。默认的情况下是‘ASC‘。
 
CREATE TABLE employee(
num INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
d_id INT NULL,
name VARCHAR(20),
age INT,
gender VARCHAR(4),
homeaddr VARCHAR(50)
) DEFAULT CHARSET=utf8;
 
INSERT INTO employee VALUES
(NULL, 1001, ‘张三‘, 26, ‘男‘, ‘北京市海淀区‘),
(NULL, 1001, ‘李四‘, 24, ‘女‘, ‘北京市昌平区‘),
(NULL, 1002, ‘王五‘, 25, ‘男‘, ‘湖南长沙市‘),
(NULL, 1004, ‘Aric‘, 15, ‘男‘, ‘England‘);
 
(1)使用SELECT语句查询employee表
select num, name, age, gender, homeaddr FROM employee;
 
(2)包括WHERE子句和ORDER BY子句的SELECT语句
SELECT num, d_id, name, age, gender, homeaddr
FROM employee
WHERE age<26
ORDER BY d_id DESC;
10.2 单表查询
单表查询是指从一张表中查询所需要的数据。查询数据时,可以从一张表中查询数据,也可以从多张表中同时查询数据。两者的查询方式有一定的区别。因为单表查询只在一张表上进行操作,所以查询比较简单。本小节将讲解在单表上查询所有的字段、查询指定的字段、查询指定的行、多条查询、查询结果不重复、给查询结果排序、分组查询和用LIMIT限制查询结果的数据等内容。
 
10.2.1 查询所有字段
查询所有字段是指查询表中所有字段的数据。这种方式可以将表中所有字段的数据都查询出来。MySQL中有两种方式可以查询表中所有的字段。
1. 列出表的所有字段
2. 使用‘*‘查询所有字段
 
 
(1)SELECT语句查询employe表中的所有字段的数据
SELECT num, d_id, name, age, gender, homeaddr FROM employee;
 
(2)用SELECT语句来查询employee表的所有字段的数据,此处用‘*‘来代替‘属性列表‘。
SELECT * FROM employee;
10.2.2 查询指定字段
查询数据时,可以在SELECT语句的‘属性列表‘中列出所有查询的字段。这种方式可以指定需要查询的字段,而不需要查询出所有的字段。下面查询employee表中num、name、gender和homeaddr这四个字段的数据。
 
SELECT num, name, gender, homeaddr FROM employee;
10.2.3 查询指定记录
SELECT语句中可以设置查询条件。用户可以根据自己的需要来设置查询条件,按条件进行查询。查询的结果必须满足查询条件。例如,用户需要查找d_id为1001的记录,那么可以设置‘d_id=1001‘为查询条件。这样查询结果中的记录就都会满足‘d_id=1001‘这个条件。WHERE子句可以用来指定查询条件。
WHEER 条件表达式
 
(1)查询employee表中d_id为1001的记录。
SELECT * FROM employee WHERE d_id=1001;
(2)查询employee表中d_id为1004的记录。
SELECT * FROM employee WHERE d_id=1004;
10.2.4 带IN关键字的查询
IN关键字可以判断某个字段的值是否在指定的集合中。如果字段的值在集合中,则满足查询条件,该记录被查询出来。如果不在集合中,则不满足查询条件。其语法规则如下:
[NOT] IN(元素1, 元素2,...,元素n)
 
查询条件 符号或关键字
比较 =, <, <=, >, >=, !=, <>, !>, !<
指定范围 BETWEEN AND, NOT BETWEEN AND
指定集合 IN, NOT IN
匹配字符 LIKE, NOT LIKE
是否为空值 IS NULL, IS NOT NULL
多个查询条件 AND, OR
 
(1)使用IN关键字查询。
SELECT * FROM employee WHERE d_id IN(1001,1004);
(2)使用NOT IN关键字查询, 而且集合元素为字符型数据。
SELECT * FROM employee WHERE name NOT IN(‘张三‘,‘李四‘);
10.2.5 带BETWEEN AND的范围查询
BETWEEN AND关键字可以判断某个字段的值是否在指定的范围内。如果字段的值在指定范围内,则满足查询条件,该记录将被查询出来。如果不在指定范围内,则不满足查询条件。其语法规则如下:
[NOT] BETWEEN 取值1 AND 取值2
 
(1)使用BETWEEN AND关键字进行查询,查询条件是age字段取值从15到25。
SELECT * FROM employee WHERE age BETWEEN 15 AND 25;
(2)使用NOT BETWEEN AND关键字查询employee表。查询条件是age字段的取值不在15到25之间。
SELECT * FROM employee WHERE age NOT BETWEEN 15 AND 25;
10.2.6 带LIKE的字符匹配查询
LIKE关键字可以匹配字符串是否相等。如果字段的值与指定的字符串相匹配,则满足查询条件,该记录将被查询出来。如果与指定的字符串不匹配,则不满足查询条件。其语法规则如下:
[NOT] LIKE ‘字符串‘
 
SELECT * FROM employee WHERE name LIKE ‘Aric‘;
SELECT * FROM employee WHERE homeaddr LIKE ‘北京%‘;
SELECT * FROM employee WHERE name LIKE ‘Ar_c‘;
SELECT * FROM employee WHERE homeaddr LIKE ‘%区‘;
10.2.7 查询空值
IS NULL 关键字可以用来判断字段的值是否为空值(NULL)。如果字段的值是空值,则满足查询条件,该记录将被查询出来。如果字段的值不是空值,则不满足查询条件。其语法规则如下:
IS [NOT] NULL
其中,‘NOT‘是可选参数,加上NOT表示字段不是空值时满足条件。
 
CREATE TABLE work(
id INT,
name VARCHAR(20),
gender VARCHAR(4),
info VARCHAR(50)
) DEFAULT CHARSET=utf8;
 
INSERT INTO work VALUES
(1001, ‘hijh‘, NULL, NULL),
(1002, ‘CCH‘, NULL, NULL),
(1003, ‘zk‘, NULL, ‘student‘);
 
SELECT * FROM work WHERE info IS NULL;
SELECT * FROM work WHERE info IS NOT NULL;
10.2.8 带AND的多条件查询
AND关键字可以用来联合多个条件进行查询。使用AND关键字时,只有同时满足所有查询条件记录会被查询出来。如果不满足这些查询条件的其中一个,这样的记录将被排除掉。AND关键字的语法规则如下:
 
条件表达式1 AND 条件表达式2 [... AND 条件表达式n]
 
其中,AND可以连接两个条件表达式。而且,可以同时使用AND关键字,这样可以连接更多的条件表达式。
SELECT * FROM employee 
WHERE d_id<1004
AND gender LIKE ‘男‘;
 
SELECT * FROM employee 
WHERE d_id<1004
AND age<26
 
INSERT INTO employee VALUES(NULL, 1002, ‘赵六‘, 22, ‘男‘, ‘延吉市开发区‘);
 
SELECT * FROM employee GROUP BY d_id, gender;
 
SELECT gender, COUNT(gender) FROM employee GROUP by gender WITH ROLLUP;
 
SELECT gender, GROUP_CONCAT(name) FROM employee GROUP BY gender WITH ROLLUP;
10.2.13 用LIMIT限制查询结果的数量
查询数据时,可能会查询出很多的记录。而用户需要的记录可能只是很少的一部分。这样就需要来限制查询结果的数量。LIMIT是MySQL中的一个特殊关键字。其可以用来指定查询结果从哪条记录开始显示。还可以指定一共显示多少条记录。LIMIT关键字有两种使用方式。这两种方式分别是不指定初始位置和指定初始位置。
 
1. 不指定初始位置
2. 指定初始位置
 
SELECT * FROM employee LIMIT 2;
SELECT * FROM employee LIMIT 6;
SELECT * FROM employee LIMIT 0, 2;
SELECT * FROM employee LIMIT 2, 2;
10.3 使用集合函数查询
集合函数包括COUNT()、SUM()、AVG()、MAX()和MIN()。其中,COUNT()用来统计记录的条件;SUM()用来计算字段的值的总和;AVG()用来计算字段的值的平均值;MAX()用来查询字段的最大值;MIN()用来查询字段的最小值。当需要对表中的记录求和、求平均值、查询最大值、查询最小值等操作时,可以使用集合函数。例如,需要计算学生成绩表中的平均成绩,可以使用AVG()函数。GROUP BY关键字通常需要与集合函数一起使用。
 
10.3.1 COUNT函数
COUNT()函数用来统计记录的条数。如果要统计employee表中有多少条记录,可以使用COUNT()函数。如果要统计employee表中不同部门的人数,也可以使用COUNT()函数。使
 
SELECT COUNT(*) FROM employee;
SELECT d_id, COUNT(*) from employee GROUP BY d_id;
10.3.2 SUM()函数
SUM()函数是求和函数。使用SUM()函数可以求出表中某个字段取值的总和。例如,可以用SUM()函数来求学生的总成绩。
 
CREATE TABLE grade(
num INT NOT NULL,
course VARCHAR(10) NOT NULL,
score FLOAT
) DEFAULT CHARSET=utf8;
 
INSERT INTO grade VALUES
(1001, ‘数学‘,  80),
(1001, ‘语文‘,  90),
(1001, ‘英语‘,  85),
(1001, ‘计算机‘, 95),
 
(1002, ‘数学‘, 88),
(1002, ‘语文‘, 90),
(1002, ‘英语‘, 89),
(1002, ‘计算机‘, 90),
 
(1003, ‘数学‘, 80),
(1003, ‘语文‘, 98),
(1003, ‘英语‘, 85),
(1003, ‘计算机‘, 95);
 
SELECT * FROM grade WHERE num=1001;
SELECT num, SUM(score) FROM grade WHERE num=1001;
SELECT num, SUM(score) FROM grade GROUP BY num;
10.3.3 AVG()函数
AVG()函数是求平均值的函数。使用AVG()函数可以求出表中某个字段取值的平均值。例如,可以用AVG()函数来求平均年龄,也可以使用AVG()函数来求学生的平均成绩。
 
SELECT AVG(age) FROM employee;
SELECT course, AVG(score) FROM grade GROUP BY course; 
SELECT num, AVG(score) FROM grade GROUP BY num;
10.3.4 MAX()函数
MAX()函数是求最大值的函数。使用MAX()函数可以求出表中某个字段取值的最大值。例如,可以用MAX()函数来查询最大年龄,也可以使用MAX()函数来求各科的最高成绩。
 
SELECT MAX(age) FROM employee; 
SELECT num, course, MAX(score) FROM grade GROUP BY course;
SELECT MAX(name) from work;
10.3.5 MIN()函数
MIN()函数是求最小值的函数。使用MIN()函数可以求出表中某个字段取值的最小值。例如,可以用MIN()函数来查询最小年龄,也可以使用MIN()函数来求各科的最小成绩。
 
SELECT MIN(age) FROM employee; 
SELECT num, course, MIN(score) FROM grade GROUP BY course;
SELECT MIN(name) from work;
10.4 连接查询
连接查询是将两个或两个以上的表按某个条件连接起来,从中选取需要的数据。连接查询是同时查询两个或两个以上的表时使用的。当不同的表中存在表示相同意义的字段时,可以通过该字段来连接这几个表。例如,学生表中有course_id字段来表示所学课程的课程号,课程表中有num字段来表示课程号。那么,可能通过学生表中的course_id字段与课程表中的num字段来进行连接查询。连接查询包括内连接查询和外连接查询。本小节将详细讲解内连接查询和外连接查询。同时,还会讲解多个条件结合在一起进行复合连接查询。
 
10.4.1 内连接查询
内连接查询是一种最常用的连接查询。内连接查询可以查询两个或两个以上的表。当两个表中存在表示相同意义的字段时,可以通过该字段来连接这两个表。当该字段的值相等时,就查询出该记录。
 
INSERT INTO department VALUES
(1004, ‘人力资源部‘, ‘管理员工的信息‘, ‘2号楼3层‘);
 
INSERT INTO employee VALUES(NULL, 1003, ‘刘花‘, 28, ‘女‘, ‘吉林省长春市‘);
INSERT INTO employee VALUES(NULL, 1006, ‘王晶‘, 22, ‘女‘, ‘吉林省通化市‘);
 
使用内连查询的方式查询
 
SELECT num, name, employee.d_id, age, d_name, function
FROM employee, department
WHERE employee.d_id=department.d_id;
10.4.2 外连接查询
外连接查询可以查询两个或两个以后的表。外连接查询也需要通过指定字段来进行连接。当该字段取值相等时,可以查询该记录。而且,该字段取值不相等的记录也可以查询出来。外连接查询包括左连接查询和右连接查询。其基本语法如下:
SELECT 属性名列表
FROM 表名1 LEFT|RIGHT JOIN 表名2
ON 表名1.属性名1 = 表名2.属性名2;
 
1. 左连接查询
SELECT num, name, employee.d_id,age,gender, d_name, function
FROM employee
LEFT JOIN department
ON employee.d_id=department.d_id;
2. 右连接查询
SELECT num, name, employee.d_id,age,gender, d_name, function
FROM employee
RIGHT JOIN department
ON employee.d_id=department.d_id;
 
CREATE TABLE performance(
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
e_num INT(10) NOT NULL UNIQUE,
performance FLOAT NOT NULL DEFAULT 0
) DEFAULT CHARSET=utf8;
 
INSERT INTO performance VALUES
(NULL, 2, 2000),
(NULL, 1, 100),
(NULL, 3, 5000),
(NULL, 5, 8000),
(NULL, 6, 10000);
 
SELECT num, name, employee.d_id,age,gender, d_name, function, performance
FROM employee
LEFT JOIN department 
ON employee.d_id=department.d_id
LEFT JOIN performance
ON employee.num=performance.id;
10.4.3 复合条件连接查询
在连接查询时,也可以增加其他的限制条件。通过多个条件的复合查询,可以使查询结果更加准备。例如,employee表和department表进行连接查询时,可以限制age字段的取值必须大于24。可以更加准备的查询出年龄大于24岁的员工的信息。
 
SELECT num,name,employee.d_id,age,gender,d_name,function
FROM employee,department
WHERE employee.d_id=department.d_id
AND age>24
ORDER BY age DESC;
10.5 子查询
子查询是将一个查询语句嵌套在另一个查询语句中。内层查询语句的查询结果,可以为外层查询语句提供查询条件。因为在特定情况下,一个查询语句的条件需要另一个查询语句来获取。例如,现在需要从学生成绩表中查询计算机系统学生的各科成绩。那么,首先就必须知道哪些课程是计算机系学生选修的。因此,必须先查询计算机系学生选修的课程,然后根据这些课程来查询计算机系学生的各科成绩。通过子查询,可以实现多表之间的查询。子查询中可能包括IN、NOT IN、ANY、ALL、EXISTS、NOT EXISTS等关键字。子查询中还可能包含比较运算符,如‘=‘、‘!=‘、‘>‘和‘<‘等。
 
10.5.1 带IN关键字的子查询
一个查询语句的条件可能在另一个SELECT语句的查询结果中。这可以通过IN关键字来判断。例如,要查询哪些同学选择了计算机系开设的课程。先必须从课程表中查询出计算机系开设了哪些课程。然后再从学生表中进行查询。如果学生选修的课程在前面查询出来的课程中,则查询出该同学的信息。这可以用带IN关键字的子查询来实现。
 
SELECT * FROM employee
WHERE d_id IN(SELECT d_id FROM department);
 
SELECT * FROM employee
WHERE d_id NOT IN(SELECT d_id FROM department);
 
10.5.2 带比较运算符的子查询
子查询可以使用比较运算符。这些比较运算符包括=、!=、>、>=、<、<=、<>等。其中,<>与!=是等价的。比较运算符在子查询时使用的非常广泛。如查询分数、年龄、价格、 收入等。
 
CREATE TABLE computer_stu(
id INT PRIMARY KEY,
name VARCHAR(20),
score FLOAT
) DEFAULT CHARSET=utf8;
 
INSERT INTO computer_stu VALUES(1001, ‘lILY‘, 85);
INSERT INTO computer_stu VALUES(1002, ‘Tom‘, 91);
INSERT INTO computer_stu VALUES(1003, ‘Jim‘, 87);
INSERT INTO computer_stu VALUES(1004, ‘Aric‘, 77);
INSERT INTO computer_stu VALUES(1005, ‘Lucy‘, 65);
INSERT INTO computer_stu VALUES(1006, ‘Andy‘, 99);
INSERT INTO computer_stu VALUES(1007, ‘Ada‘, 85);
INSERT INTO computer_stu VALUES(1008, ‘jeck‘, 70);
 
CREATE TABLE scholarship(
level INT PRIMARY KEY,
score INT
) DEFAULT CHARSET=utf8;
 
INSERT INTO scholarship VALUES(1, 90);
INSERT INTO scholarship VALUES(2, 80);
INSERT INTO scholarship VALUES(3, 70);
 
在computer_stu表中查询获得一等奖学金的学生的学号、姓名和分数。各个等级的奖学金的最低存储在scholarship表中。
 
SELECT id, name, score, FROM computer_stu
WHERE score>=(SELECT score FROM scholarship WHERE level=1)
 
在department表中查询哪些部门没有年龄为24岁的员工。员工的年龄存储在employee表中。先查询一下employee表和deparment表,以便进行对比。
SELECT d_id, d_name
FROM department
WHERE d_id!=(SELECT d_id FROM employee WHERE age=24);
SELECT d_id, d_name
FROM department
WHERE d_id<>(SELECT d_id FROM employee WHERE age=24);
10.5.3 带EXISTS关键字的子查询
EXISTS关键字表示存在。使用EXISTS关键字时,内层查询语句不返回查询的记录。而是返回一个真假值。如果内层查询语句查询到满足条件的记录,就返回一个真值(TRUE)。否则,将返回一个假值(FALSE)。当返回的值是真值时,外层查询语句将进行查询。当返回值是假值时,外层查询语句不再进行查询或者查询不出任何记录。
 
 
如果department表中存在d_id取值为1003的记录,则查询employee表的记录
SELECT * FROM employee
WHERE EXISTS(SELECT d_name FROM department WHERE d_id=1003);
 
如果department表中存在d_id取值为1003的记录,则查询employee表中age大于24的记录
 
SELECT * FROM employee
WHERE age>24 AND EXISTS(SELECT d_name FROM department WHERE d_id=1006);
 
如果department表中不存在d_id取值为1003的记录,则查询employee表的记录
 
SELECT * FROM employee
WHERE NOT EXISTS(SELECT d_name FROM department WHERE d_id=1006);
10.5.4 带ANY关键字的子查询
ANY关键字表示满足其中任一条件。使用ANY关键字时,只要满足内层查询语句返回的结果中的任何一个,就可以通过该条件来执行外层查询语句。例如,需要查询哪些同学能够获得奖学金。那么,首先必须从奖学金表中查询出各种奖学金要求的最低分。只要一个同学的成绩高于不同奖学金最低分的任何一个,这个同学就可以获得奖学金。ANY关键字通常与比较运算符一起使用。
 
从computer_stu表中查询哪些同学可以获得奖学金。奖学金的信息存储在scholarship表中。
 
SELECT * FROM computer_stu WHERE score>=ANY
(SELECT score FROM scholarship);
10.5.5 带ALL关键字的子查询
ALL关键字表示满足所有条件。使用ALL关键字时,只有满足内层查询语句返回的所有结果,才可以执行外层查询语句。例如,需要查询哪些同学能够获得一等奖学金。首先必须从奖学金表中查询出各种奖学金要求的最低分。因为一等奖金要求的分数最高。只有当同学的成绩高于所有奖学金最低分时,这个同学才可能获得等奖学金。ALL关键字也经常与比较运算符一起使用。
 
SELECT * FROM computer_stu
WHERE score>=ALL(SELECT score FROM scholarship);
10.6 合并查询结果
合并查询结构是将多个SELECT语句的查询结果合并到一起。因为某种情况下,需要将几个SELECT语句查询出来的结果合并起来显示。例如,现在需要查询公司甲和公司乙这两个公司所有员工的信息。这就需要从公司甲中查询出所有员工的信息,再从公司乙查询出所有员工的信息。然后将两次的查询结果合并到一起。进行合并操作使用UNION和UNION ALL关键字。
 
使用UNION关键字时,数据库系统会将所有的查询结果合并到一起,然后去除相同的记录。而UNION ALl关键字则只是简单的合并到一起。
 
SELECT语句1
UNION | UNION ALL
SELECT语句2
UNION | UNION ALL...
SELECT语句n;
 
SELECT d_id FROM department;
SELECT d_id FROM employee;
 
SELECT d_id FROM department
UNION
SELECT d_id FROM employee;
 
SELECT d_id FROM department
UNION ALL
SELECT d_id FROM employee;
10.7 为表和字段取别名
在查询时,可以为表和字段取一个别名。这个别名可以代替其指定的表和字段。
 
10.7.1 为表取别名
当表的名称特别长时,在查询中直接使用表名很不方便。这时可以为表取一个别名。用这个别名代替表的名称。例如,电力软件中的变压器的名称为power_system_transform。如果要使用该表下面的字段id,但同时查询的其他表中也有id字段。这样就必须指明是哪个表下的id字段,如power_system_transform.id。因为变压器表的表名太长,使用起来不是很方便。为了解决这个问题,可以将变压器表取一个别名。如将power_system_transform取个别名为t,那么t就代表了变压器表。t.id就与power_system_transform.id表示的意思相同了。
 
MySQL 中为表取别名的基本形式如下:
表名 表的别名
 
SELECT * FROM department [AS] D WHERE d.d_id=1001;
10.7.2 为字段取别名
当查询数据时,MySQL会显示每个输出列的名词。默认的情况下,显示的列名是创建表是定义的列名。例如,department表的列名分别是d_id、d_name、function和address。当查询department表时,就会相应显示这几个列名。有时为了显示结果更加直观,需要一个更加直观的名字来表示这一列。如department_name可以很直接的知道是部门名称。这时就需要将d_name字段取别名为deparment_name。
 
属性名 [AS] 别名
 
SELECT d_id AS department_id, d_name AS department_name FROM department;
 
SELECT d.d_id AS department_id, d.d_name AS department_name, d.function, d.address FROM department d WHERE d.d_id=1001;
10.8 使用正则表达式查询
正则表达式是用某种模式去匹配一类字符串的一个方式。例如,使用正则表达式可以查询出包含A、B、C其中任一字母的字符串。正则表达式的查询能力比通配字符的查询能力更强大,而且更加的灵活。正则表达式可以应用于非常复杂查询。
 
属性名 REGEXP ‘匹配方式‘
 
正则表达式的模式字符
 
模式字符 含义
^ 匹配字符串开始的部分
$ 匹配字符串结尾的部分
. 代表字符串中的任意一个字符,包括回车和换行
[字符集合] 匹配‘字符集合‘中的任何一个字符
[^字符集合] 匹配除了‘字符集合‘中的以外的任何一个字符
S1|S2|S3 匹配S1、S2、S3中的任意一个字符串
* 代表多个该字符之前的字符,包括0和1个
+ 代表多个该符号之前的字符,包括1个
字符串{N} 字符串出现N次
字符串{M,N} 字符串出现至少M次,最多N次
 
10.8.1 查询以特定字符或字符串开头的记录
使用字符‘^‘可以匹配特定字符或字符串开头的记录。下面从info表name字段中查询以字母‘L‘开头的记录。
 
 
CREATE TABLE info(
id INT,
name VARCHAR(20)
) DEFAULT CHARSET=utf8;
 
INSERT INTO info VALUES(1, ‘Aric‘);
INSERT INTO info VALUES(2, ‘Eric‘);
INSERT INTO info VALUES(3, ‘Jame‘);
INSERT INTO info VALUES(4, ‘Jack‘);
INSERT INTO info VALUES(5, ‘Lucy‘);
INSERT INTO info VALUES(6, ‘Lily‘);
INSERT INTO info VALUES(7, ‘Tom‘);
INSERT INTO info VALUES(8, ‘aaa‘);
INSERT INTO info VALUES(9, ‘dadaaa‘);
INSERT INTO info VALUES(10, ‘2323‘);
INSERT INTO info VALUES(11, ‘bbdfec12‘);
INSERT INTO info VALUES(12, ‘212abc‘);
INSERT INTO info VALUES(17, ‘werabc‘);
 
SELECT * FROM info WHERE name REGEXP ‘^L‘;
SELECT * FROM info WHERE name REGEXP ‘^aaa‘;
10.8.2 查询以特定字符或字符串结尾的记录
SELECT * FROM info WHERE name REGEXP ‘c$‘;
# SELECT * FROM info WHERE name REGEXP ‘aaa$‘;
10.8.3 用符号‘.‘来替代字符串任意一个字符
# SELECT * FROM info WHERE name REGEXP ‘^L..y$‘;
10.8.4 匹配指定字符串的任意一个
使用方括号([])可以将需要查询字符组成一个字符集。只要记录中包含方括号中的任意字符,该记录将会被查询出来。例如,通过"[abc]"可以查询包括a、b、c这三个字母中任何一个的记录。
 
SELECT * FROM info WHERE name REGEXP ‘[ceo]‘;
SELECT * FROM info WHERE name REGEXP ‘[0-9]‘;
10.8.5 匹配指定字符以外的字符
使用‘[^字符集合]‘可以匹配指定字符以外的字符。从info表字段中查询包含a到w字母和数字以外的字符的记录。
 
SELECT * FROM info WHERE name REGEXP ‘[^a-w0-9]‘;
10.8.6 匹配指定字符串
正则表达式可以匹配字符串。当表中的记录包含这个字符串时,就可以将该记录查询出来。如果指定多个字符串时,需要用符号‘|‘隔开。只要匹配这些字符串中的任意一个即可。
 
SELECT * FROM info WHERE name REGEXP ‘ic‘;
SELECT * FROM info WHERE name REGEXP ‘ic|ab|uc‘;
10.8.7 使用‘*‘和‘+‘来匹配多个字符
正则表达式中,‘*‘和‘+‘都可以匹配多个该符号之间的字符。但是,‘+‘至少表示一个字符,而‘*‘可以表示零个字符。
 
SELECT * FROM info WHERE name REGEXP ‘a*c‘;
SELECT * FROM info WHERE name REGEXP ‘a+c‘;
10.8.8 使用{M}或者{M,N}来指定字符串连续出现的次数
正则表达式中,‘字符串{M}‘表示字符串连续出现M次;‘字符串{M,N}‘表示字符串联连续出现至少M次,最多N次。例如,‘ab{2}‘表示字符串‘ab‘连续出现两次。‘ab{2,4}‘表示字符串‘ab‘连续出现至少两次,最多四次。
 
SELECT * FROM info WHERE name REGEXP ‘a{3}‘;
SELECT * FROM info WHERE name REGEXP ‘ab{1,3}‘;
10.9 本章实例
student表结构
 
字段名 字段描述 数据类型 主键 外键 非空 唯一 自增
id 学号 INT(10) 是   否    是 是   否
name 姓名 VARCHAR(20) 否   否    是   否   否
gender 性别 VARCHAR(4) 否   否    否   否   否
birth 出生年份 YEAR 否   否    否   否   否
department 院系 VARCHAR(20) 否   否    是   否   否
address 家庭住址 VARCHAR(50) 否   否    否   否   否
 
score表结构
 
字段名 字段描述 数据类型 主键 外键 非空 唯一 自增
id 编号 INT(10) 是   否    是 是   是
stu_id 学号 INT(10) 否   否    是   否   否
c_name 课程名 VARCHAR(20) 否   否    否   否   否
grade 分数 INT(10) 否   否    否   否   否
 
 
student表的记录
 
id name gender birth department address
901 张老大 男 1985 计算机系 北京市海淀区
902 张老二 男 1986 中文系 北京市昌平区
903 张三 女 1990 中文系 湖南省永州区
904 李四 男 1990 英语系 辽宁省阜新市
905 王五 女 1991 英语系 福建省厦门市
906 王六 男 1988 计算机系 湖南省衡阳市
 
 
score表的记录
 
id stu_id c_name grade
1 901 计算机 98
2 901 英语 80
3 902 计算机 65
4 902 中文 88
5 903 中文 95
6 904 计算机 70
7 904 英语 92
8 905 英语 94
9 906 计算机 90
10 906 英语 85
 
 
执行操作如下:
(1)先按照以上两个表的结构创建表studetn和表socre。
(2)给两个表增加记录
(3)查询student表的所有记录
(4)查询studnet表的第二条到第四条
(5)从student表查询所有学生的学号、姓名和院系的信息。
(6)从student表中查询计算机系和英语系的学生的信息
(7)从student表中查询年龄为18到22岁的学生的信息
(8)从student表中查询每个院系有多少人
(9)从score表中查询每个科目的最高分。
(10)查询李四的考试科目和考试成绩
(11)用连接查询的方式查询所有学生的信息和考试信息
(12)计算每个学生的总成绩
(13)计算每个考试科目的平均成绩
(14)查询计算机成绩低于95的学生的信息
(15)查询同时参加计算机和英语系考试的学生的信息
(16)将计算机考试成绩按从高到低进行排序
(17)从student表和score表中查询出学生的学号、然后合并查询结果
(18)查询姓张或者姓王同学的姓名、院系、考试科目和成绩
(19)查询都是湖南的同学的姓名、年龄、院系、考试科目和成绩
 
CREATE TABLE student(
id INT(10) NOT NULL UNIQUE PRIMARY KEY,
name VARCHAR(20) NOT NULL,
gender VARCHAR(4),
birth YEAR,
department VARCHAR(20) NOT NULL,
address VARCHAR(50)
) DEFAULT CHARSET=utf8;
 
CREATE TABLE score(
id INT(10) NOT NULL UNIQUE PRIMARY KEY AUTO_INCREMENT,
stu_id INT(10) NOT NULL,
c_name VARCHAR(20),
grade INT(10)
) DEFAULT CHARSET=utf8;
 
 
INSERT INTO student VALUES
(901,‘张老大‘,‘男‘,‘1985‘,‘计算机系‘,‘北京市海淀区‘),
(902,‘张老二‘,‘男‘,‘1986‘,‘中文系‘,‘北京市昌平区‘),
(903,‘张三‘,‘女‘,‘1990‘,‘中文系‘,‘湖南省永州区‘),
(904,‘李四‘,‘男‘,‘1990‘,‘英语系‘,‘辽宁省阜新市‘),
(905,‘王五‘,‘女‘,‘1991‘,‘英语系‘,‘福建省厦门市‘),
(906,‘王六‘,‘男‘,‘1988‘,‘计算机系‘,‘湖南省衡阳市‘);
 
INSERT INTO score VALUES
(NULL, 901, ‘计算机‘, 98),
(NULL, 901, ‘英语‘, 80),
(NULL, 902, ‘计算机‘, 65),
(NULL, 902, ‘中文‘, 88),
(NULL, 903, ‘中文‘, 95),
(NULL, 904, ‘计算机‘, 70),
(NULL, 904, ‘英语‘, 92),
(NULL, 905, ‘英语‘, 94),
(NULL, 906, ‘计算机‘, 90),
(NULL, 906, ‘英语‘, 85);
 
(3)SELECT * FROM student;
(4)SELECT * FROM student LIMIT 1,3
(5)SELECT id, name, department FROM student;
(6)SELECT * FROM student WHERE department IN(‘计算机系‘,‘英语系‘);
     SELECT * FROM student WHERE department=‘计算机系‘ OR department=‘英语系‘;
(7)SELECT * FROM student WHERE YEAR(NOW())-birth BETWEEN 18 AND 22;
(8)SELECT department, COUNT(id) as sum_of_department FROM student GROUP BY department;  
(9)SELECT c_name, MAX(grade) FROM score GROUP BY c_name;
(10) SELECT c_name, grade 
FROM score 
WHERE stu_id=(SELECT id FROM student WHERE name=‘李四‘); 
(11)SELECT student.id, name, gender, birth, department, address, c_name,grade 
FROM student, score
WHERE student.id=score.stu_id;
 
(12)SELECT stu_id, SUM(grade) FROM score GROUP BY stu_id;
      SELECT student.id, name, SUM(grade)
      FROM student, score
      WHERE student.id=score.stu_id
      GROUP BY student.id;
 
(13)SELECT c_name, AVG(grade) FROM score GROUP BY c_name; 
(14)SELECT * FROM student
WHERE id IN(
SELECT stu_id FROM score
WHERE c_name=‘计算机‘ AND grade<95
 
 
11.1.4 使用REPLACE语句替换数据
如果使用INSERT语句插入数据时,在表中已经有相同数据时(指的是PRIMARYT KEY或UNIQUE字段相同数据)会发生错误。而REPLACE INTO语句会删除原有相同数据而插入新的数据。
INSERT INTO product VALUES
(1005, ‘头疼灵1号‘, ‘治疗头疼‘, ‘DD制药厂‘, ‘北京市房山区‘);
 
REPLACE INTO product VALUES
(1005, ‘头疼灵1号_replace‘, ‘治疗头疼‘, ‘DD制药厂‘, ‘北京市房山区‘);
11.2 更新数据
更新数据是更新表中已经存在的记录。通过这种方式可以改变表中已经存在的数据。例如。学生表中某个学生的家庭住址改变了,这就需要在学生表中修改该同学的家庭地址。MySQL中,通过UPDATE语句来更新数据。
MySQL中,UPDATE语句的基本语法形式如下:
UPDATE 表名
SET 属性名1=取值1,属性名2=取值3,
...,
属性名n=取值n
WHERE 条件表达式;
 
UPDATE product 
SET function=‘保护皮肤的护肤品‘, address=‘吉林省延吉市开发区‘
WHERE id=1004;
 
UPDATE product
SET function=‘护理头发‘, address=‘北京市昌平区‘
WHERE id >=1008 AND id<=1010;
 
ALTER TABLE product
ADD price FLOAT(5,2) DEFAULT 0 COMMENT ‘价格‘;
 
ALTER TABLE product MODIFY price FLOAT(5,2) DEFAULT 0 AFTER name;
 
UPDATE product
SET price=330
WHERE id=1001;
 
UPDATE product
SET price=price+100
WHERE id=1001;
11.3 删除记录
删除数据是删除表中已经存在的记录。通过这种方式可以删除表中不再使用的记录。例如,学生表中某个学生退学了,这就需要从学生表中删除该同学的信息。MySQL中,通过DELETE语句来删除数据。MySQL中,DELETE语句的基本语法形式如下:
DELETE FROM 表名[WHERE 条件表达式];
 
DELETE FROM product WHERE id=1001;
 
DELETE FROM product; # 删除product表中的所有记录
TRUNCATE TABLE product; # 删除product表中的所有记录
11.4 本章实例
(1)创建表food表
food表的结构
 
字段名 字段描述 数据类型 主键 外键 非空 唯一 自增
id 编号 INT(10) 是 否 是 是 是
name 食品名称 VARCHAR(20) 否 否 是 否 否
company 生产厂商 VARCHAR(30) 否 否 是 否 否
price 价格(单位:圆) FLOAT 否 否 否 否 否
product_year 生产年份 YEAR 否 否 否 否 否
validity_m 保质期(单位:月)TINYINT(3) 否 否 否 否 否
address 厂址 VARCHAR(50) 否 否 否 否 否
 
(2)向以列数据插入到food表中
food表的内容
 
id name company  price product_year validity_time address
1 AA饼干 AA饼干厂 2.5 2008 36 北京
2 CC牛奶 CC饼干厂 3.5 2009 12 河北
3 EE果冻 EE饼干厂 1.5 2007 24 北京
4 FF咖啡 FF饼干厂 20 2006 60 天津
5 GG奶糖 GG饼干厂 14 2010 36 广东
 
(3)将"CC牛奶厂"的厂址(address)必为"内蒙古",并且将价格必为3.2。
(4)将厂址在北京的公司的保质斯为都改为5年。
(5)删除过期食品的记录。若当前时间-生产年份 > 保质期,则视为过期食品。
 
USE example;
CREATE TABLE food(
id INT(10) NOT NULL UNIQUE PRIMARY KEY AUTO_INCREMENT COMMENT ‘编号‘,
name VARCHAR(20) NOT NULL COMMENT ‘食品名称‘,
company VARCHAR(30) NOT NULL COMMENT ‘生产厂商‘,
price FLOAT COMMENT ‘价格‘,
product_year YEAR COMMENT ‘生产年份‘,
validity_m TINYINT(3) COMMENT ‘保质期‘,
address VARCHAR(50) COMMENT ‘厂址‘
) DEFAULT CHARSET=utf8;
 
INSERT INTO food VALUES (1,‘AA饼干‘,‘AA饼干厂‘,2.5,‘2008‘,36,‘北京‘);
 
INSERT INTO food(id, name, company, price, product_year, validity_m, address)
VALUES(2,‘CC牛奶‘,‘CC饼干厂‘,3.5,‘2009‘,12,‘河北‘);
 
INSERT INTO food VALUES
(NULL, ‘EE果冻‘, ‘EE饼干厂‘, 1.5, ‘2007‘, 24, ‘北京‘),
(NULL, ‘FF咖啡‘, ‘FF饼干厂‘, 20, ‘2006‘, 60, ‘天津‘),
(NULL, ‘GG奶糖‘, ‘GG饼干厂‘, 14, ‘2010‘, 36, ‘广东‘);
 
UPDATE food SET address=‘内蒙古‘, price=3.2 WHERE company=‘CC饼干厂‘;
UPDATE food SET validity_m=60 WHERE address=‘北京‘;
DELETE FROM food WHERE YEAR(NOW())-product_year > validity_m/12;
DELETE FROM food WHERE address=‘北京‘;
11.5 常见问题及解答
1. 插入记录时,哪种情况不需要在INSERT语句中指定字段名?
答:INSERT语句中指定字段名为了指明将数据插入到那个字段中。如果INSERT语句为表中的所有字段赋值时,就可以不需要指明字段名。数据库系统会按顺序将数据依次插入到所有字段中。有些表的字段特别多,有些字段不要赋值。这样就必须指明为哪些字段赋值。
2. 如何为自增字段(AUTO_INCREMENT)赋值?
答:在INSERT语句中可以直接为自增字段赋值。但是,大部分的自增字段是需要数据库系统为其自动生成一个值的。这样可以保证这个值的惟一性。用户可以通过两种方式来让数据库系统自动为自增字段赋值。第一种方法是在INSERT语句中不为该字段赋值。第二种方法是在INSERT语句中将该字段赋值为NULL。这两种情况下,数据库系统自动为自增字段赋值。而且,其值是上条记录中该字段的取值值加一。
3. 如何进行联表删除?
答:如果某个学生退学了,那么就必须从学生表中删除这个学生信息。同时,必须从数据库中删除所有与该同学图书信息、成绩信息等。这就是必须删除。在删除学生表中这个学生的信息时,要同时删除所有其它表中该同学的信息。这个可以通过外键来实现。其它表中的信息与学生表中的信息都是通过学号来联系的。根据学号查询存在该同学信息的表,删除相应的数据。联表删除可以保证数据库中数据的一致性。

查询数据

标签:

原文地址:http://www.cnblogs.com/songjy2116/p/5220661.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!