DQL( Data Query Language 数据查询语言 )是查询数据库数据的语言 , 如SELECT语句,包括简单的单表查询或多表的复杂查询和嵌套查询等,是数据库语言中最核心、最重要的语句,也是使用频率最高的语句。
#[]中代表可选的,{}中为必选的
SELECT [ALL | DISTINCT] #[ALL | DISTINCT] 全部/去重复
{* | 表名.* | [表名.字段名1[as 别名1][,表名.字段名2[as 别名2]][,...]]}
FROM 要查询的表名 [as 表别名]
[left | right | inner join 连接表名] #连接查询
[WHERE ...] # WHERE条件子句 指定结果需满足的条件
[GROUP BY ...] #指定结果按照哪几个字段来分组
[HAVING] #次条件子句 过滤分组的记录必须满足的次要条件
[ORDER BY ...] #指定查询记录按一个或多个条件排序 升序ASC 降序DESC
[LIMIT {[offset,]row_count | row_countOFFSET offset}];#指定查询的记录从哪条至哪条
查询表结果时 , 可指定查询结果的数据列
查询表中所有的数据列结果 , 采用 " * " 符号;
如 :
SELECT * FROM student;# 查询所有学生信息
但是效率低 , 不推荐
推荐查询需要的结果列:
# 查询指定列(学号 , 姓名)
SELECT studentno,studentname FROM student;
作用 : 去掉SELECT查询返回的记录结果中重复的记录(返回所有列的值都相同),只返回一条
SELECT studentno FROM result; # 查看哪些同学参加了考试(学号)
SELECT DISTINCT studentno FROM result;# 查看哪些同学参加了考试(学号),无重复
#DISTINCT 去除重复项 , (默认是ALL)
AS子句作用 :
SELECT studentno,studentname FROM student AS s;
SELECT studentno AS 学号,studentname AS 姓名 FROM student;#as关键词可以省略
# CONCAT()函数拼接字符串
SELECT CONCAT('姓名:',studentname) AS 新姓名 FROM student;
数据库中的表达式一般由文本值、列值、NULL、函数和操作符等组成。
应用场景 :
# selcet查询中可以使用表达式
SELECT @@auto_increment_increment; # 查询自增步长
SELECT VERSION(); #查询版本号
SELECT 100*3-1 AS 计算结果; # 表达式
# 学员考试成绩集体提分一分查看
SELECT studentno,StudentResult+1 AS '提分后' FROM result;
操作符名称 | 语法 | 描述 |
---|---|---|
AND或&& | a AND b 或 a&&b | 逻辑与,同时为真结果才为真 |
OR或|| | a OR b 或 a || b | 逻辑或,只要有一个为真则结果为真 |
NOT或! | NOT a 或 !a | 逻辑非,若操作数为假,则结果为真 |
操作符名称 | 语法 | 描述 |
---|---|---|
IS NULL | a IS NULL | 若操作符为NULL,则结果为真 |
IS NOT NULL | a IS NOT NULL | 若操作符不为NULL,则结果为真 |
BETWEEN AND | a BETWEEN b AND c | 若a范围在b与c之间,则结果为真 |
LIKE | a LIKE b | SQL模式匹配,若a匹配b,则结果为真 |
IN | a IN(a1,a2,a3…) | 若a等于a1,a2,a3…中的某一个,则结果为真 |
注意 :
数值数据类型的记录之间才能进行逻辑运算操作;
相同数据类型的数据之间才能进行比较操作。
查询考试成绩在95-100之间的学生学号(BETWEEN AND)
SELECT Studentno
FROM result
WHERE StudentResult>=95 AND StudentResult<=100;# AND也可以写成 &&
SELECT studentno,studentresult
FROM result
WHERE studentno=1000 AND studentresult>90;
SELECT studentno,studentresult
FROM result
WHERE NOT studentno=1000;
一般包括BETWEEN AND、LIKE、IN、NULL等比较操作符。
举例:
SELECT Studentno,StudentResult
FROM result
WHERE StudentResult BETWEEN 95 AND 100;
LIKE结合使用的通配符 :
% (代表0到任意个字符)
_ (代表一个字符)
查询姓李的同学的学号及姓名
SELECT studentno,studentname FROM student
WHERE studentname LIKE '李%';
SELECT studentno,studentname FROM student
WHERE studentname LIKE '李_';
查询姓李的同学,姓名为三个字的
SELECT studentno,studentname FROM student
WHERE studentname LIKE '李__';
查询姓名中含有“文”字的(“文”字出现的位置不限)
SELECT studentno,studentname FROM student
WHERE studentname LIKE '%文%';
注意:
查询姓名中含有特殊字符的需要使用转义符号 '\'
自定义转义符关键字: ESCAPE ':'
查询学号为1000、1001、1002的学生姓名
SELECT studentno,studentname FROM student
WHERE studentno IN (1000,1001,1002);
SELECT studentno,studentname,address FROM student
WHERE address IN ('安徽','河南洛阳');
查询出生日期没有填写的同学
SELECT studentname FROM student
WHERE BornDate IS NULL;#不能直接写=NULL , 这是代表错误的 , 用 is null
查询填写了出生日期的同学
SELECT studentname,BornDate FROM student
WHERE BornDate IS NOT NULL;
SELECT studentname FROM student
WHERE Address='' OR Address IS NULL;
说明:组合两个表中的记录,返回关联字段相符的记录,也就是返回两个表的交集(阴影)部分。
语法:
SELECT <列名1>,<列名2>,...
FROM <表1> a
INNER JOIN <表2> b
ON <条件子句>
#a为表1别名,b为表2别名
举例:
SELECT s.studentno,studentname,subjectno,studentresult
FROM student s
INNER JOIN result r
ON r.studentno = s.studentno #此处为等值连接,如果为小于或大于号则为不等连接
#注意:因为 student表和 result表都有studentno这一列,所以如果studentno前面不指定是哪个表的会报错
/*错误代码: 1052
Column 'studentno' in field list is ambiguous
*/
说明:left join 是left outer join的简写,它的全称是左外连接,是外连接中的一种。 左(外)连接,左表的记录将会全部表示出来,而右表只会显示符合搜索条件的记录。右表记录不足的地方均为NULL。
语法:
SELECT <列名1>,<列名2>,...
FROM <表名1> a
LEFT JOIN<表名2> b
ON <条件子句>
举例:
SELECT s.studentno,studentname,subjectno,studentresult
FROM student s
LEFT JOIN result r
ON r.studentno = s.studentno
#左表为student,右表为result,因此该例含义为查询了所有同学,没考试成绩的也会查出来
SELECT s.studentno,studentname,subjectno,studentresult
FROM student s
LEFT JOIN result r
ON r.studentno = s.studentno
WHERE studentresult IS NULL
说明:right join是right outer join的简写,它的全称是右外连接,是外连接中的一种。与左(外)连接相反,右(外)连接,左表只会显示符合搜索条件的记录,而右表的记录将会全部表示出来。左表记录不足的地方均为NULL。
语法:
SELECT <列名1>,<列名2>,...
FROM <表名1> a
RIGHT JOIN <表名2> b
ON <条件子句>
举例:
SELECT s.studentno,studentname,subjectno,studentresult
FROM student s
RIGHT JOIN result r
ON r.studentno = s.studentno
#左表为student,右表为result,因此该例含义为查询了有成绩的同学
说明:自连接查询其实等同于连接查询,需要两张表,只不过它的左表(父表)和右表(子表)都是自己。做自连接查询的时候,是自己和自己连接,分别给父表和子表取两个不同的别名,然后附上连接条件
举例:
先构造一个表并插入数据
CREATE TABLE object(
id SMALLINT PRIMARY KEY AUTO_INCREMENT,
object_name VARCHAR(20) NOT NULL,
parent_id SMALLINT NOT NULL
)ENGINE=INNODB DEFAULT CHARSET=utf8;
INSERT INTO object(object_name, parent_id) VALUES('数码产品', 0);
INSERT INTO object(object_name, parent_id) VALUES('家用产品', 0);
INSERT INTO object(object_name, parent_id) VALUES('笔记本', 1);
INSERT INTO object(object_name, parent_id) VALUES('智能手机', 1);
INSERT INTO object(object_name, parent_id) VALUES('电器', 2);
INSERT INTO object(object_name, parent_id) VALUES('家具', 2);
INSERT INTO object(object_name, parent_id) VALUES('冰箱', 5);
INSERT INTO object(object_name, parent_id) VALUES('洗衣机', 5);
INSERT INTO object(object_name, parent_id) VALUES('汽车品牌', 0);
INSERT INTO object(object_name, parent_id) VALUES('别克', 9);
INSERT INTO object(object_name, parent_id) VALUES('宝马', 9);
INSERT INTO object(object_name, parent_id) VALUES('雪佛兰', 9);
INSERT INTO object(object_name, parent_id) VALUES('家纺', 0);
SELECT a.object_name,b.object_name AS '父类'
FROM object a,object b #这里将自己看做两张独立的表,做自连接查询
WHERE a.parent_id=b.id;
说明: ORDER BY 语句用于根据指定的列对结果集进行排序;
ORDER BY 语句默认按照ASC升序对记录进行排序;
如果希望按照降序对记录进行排序,可以使用 DESC 关键字。
举例:
SELECT s.studentno,studentname,subjectname,studentresult
FROM student s
INNER JOIN result r
ON r.studentno = s.studentno
INNER JOIN `subject` subj
ON r.subjectno = subj.subjectno
WHERE subjectname='高等数学-4'
ORDER BY studentresult DESC , studentno;
语法 : SELECT * FROM table LIMIT [offset,] rows | rows OFFSET offset
好处 : (用户体验好、网络传输快、查询压力小)
推导:
第一页 : LIMIT 0,5
(显示前五条信息,等同于LIMIT 5
)
第二页 : LIMIT 5,5
(显示第二页的五条信息)
第三页 : LIMIT 10,5
…
第N页 : LIMIT (pageNo-1)*pageSize,pageSize
其中pageNo
:页码,pageSize
:单页面显示条数
举例:
SELECT s.studentno,studentname,subjectname,StudentResult
FROM student s
INNER JOIN result r
ON r.studentno = s.studentno
INNER JOIN `subject` sub
ON r.subjectno = sub.subjectno
WHERE subjectname='数据库结构-1'
ORDER BY StudentResult DESC , studentno
LIMIT 0,5;
概念:
在查询语句中的WHERE条件子句中,又嵌套了另一个查询语句;
嵌套查询可由多个子查询组成,求解的方式是由里及外;
子查询返回的结果一般都是集合,故而建议使用IN关键字。
举例:
查询“数据库结构-1”科目的成绩并按降序排列
SELECT studentno,subjectno,StudentResult
FROM result
WHERE subjectno=(
SELECT subjectno FROM `subject`
WHERE subjectname = '数据库结构-1'
)
ORDER BY studentresult DESC;
一题多解:
查询课程为 高等数学-2 且分数不小于80分的学生的学号和姓名
#方法一:使用连接查询
SELECT s.studentno,studentname
FROM student s
INNER JOIN result r
ON s.studentno = r.studentno
INNER JOIN subject sub
ON sub.subjectno = r.subjectno
WHERE subjectname = '高等数学-2' AND studentresult>=80
#方法二:使用连接查询+子查询
SELECT r.studentno,studentname FROM student s
INNER JOIN result r ON s.studentno=r.studentno
WHERE studentresult>=80 AND subjectno=(
SELECT subjectno FROM subject
WHERE subjectname = '高等数学-2'
)
#方法三:使用子查询
#分步写简单sql语句,然后将其嵌套起来
SELECT studentno,studentname FROM student WHERE studentno IN(
SELECT studentno FROM result WHERE studentresult>=80 AND subjectno=(
SELECT subjectno FROM subject WHERE subjectname = '高等数学-2'
)
)