外键作用
创建外键:
建表是指定外键约束
建表后修改
删除外键
删除外键、删除表
语法:
ALTER TABLE 表名 ADD CONSTRAINT 主键名
PRIMARY KEY 表名(主键字段);
问题:
如何设置grade表中gradeId字段为主键?
ALTER TABLE `grade` ADD CONSTRAINT `pk_grade`
PRIMARY KEY `grade`(`gradeId`);
语法:
ALTER TABLE 子表名 ADD CONSTRAINT 起的外键名
FOREIGN KEY(外键字段)
REFERENCES 关联/主表名(关联字段);
问题:
如何将student表的gradeId字段和grade表的主键:gradeId字段建立外键关联?
ALTER TABLE `student` ADD CONSTRAINT fk_student_grade
FOREIGN KEY(`gradeId`)
REFERENCES `grade` (`gradeId`);
#年级表(id/年级名称)
CREATE TABLE IF NOT EXISTS grade(
gradeId INT(10) PRIMARY KEY AUTO_INCREMENT,
gradename VARCHAR(50) NOT NULL
);
#学生信息表(学号、姓名、性别、年级、手机号、地址、出生日期、电子邮箱、身份证号)
CREATE TABLE student(
studentno INT (4) PRIMARY KEY;
sudentname VARCHAR(20) NOT NULL DEFAULT '匿名',
sex TINYINT(1) DEFAULT1,
gradeid INT (10),
phone VARCHAR(50) NOT NULL,
address VARCHAR(255) ,
email VARCHAR(50),
identityCard VARCHAR(18) NOT NULL ,
#创建一个外键约束----把**设置为外键给**引用
CONSTRAINT FK_gradeid FOREIGN KEY(gradeid) REFERENCES grade(gradeid)
);
CREATE TABLE student(
studentno INT (4) PRIMARY KEY;
sudentname VARCHAR(20) NOT NULL DEFAULT '匿名',
sex TINYINT(1) DEFAULT1,
gradeid INT (10),
phone VARCHAR(50) NOT NULL,
address VARCHAR(255) ,
email VARCHAR(50),
identityCard VARCHAR(18) NOT NULL
);
ALTER TABLE `table1`ADD CONSTRAINT FK_gradeid
FOREIGN KEY(gradeid)
REFERENCES grade(gradeid);
删除具有主外键关系的表是,要先删除子表,再删主表!
删除外键:
ALERT TABLE student DROP FOREIGN KEY FK_gradeid ;
ALERT TABLE student DROP INDEX KEY FK_gradeid ;
数据库意义:
数据存储;
数据管理。
管理数据库数据方法:
通过SQLyog等管理工具管理数据库数据;
通过DML语句管理数据库数据。
SELECT* FROM 表名
指定查询字段:
查询表结果时,可指定查询结果的数据列
查询表中所有的数据列结果,采用 * 符号;
例如:
select * from student ; ------------效率低,不推荐
可指定查询的结果数据列:
如只查询student表中的学号、姓名、电话:
SELECT StudentNo,StudentName,Phone FROM student ;
如区分连接查询时两个表有同名的字段:
SELECT student.StudentNo,StudentName,StudentResult FROM student , result ;
----可指定该字段属于哪个表
AS子句作用:
AS子句用法
如:
SELECT StudentNo AS “学号” FROM student ;
SELECT a.StudentNo FROM student AS a ;
SELECT Phone+1 AS Tel FROM student ;
------AS也可以省略不写
DISTINCT关键字
作用:
去掉SELECT查询返回的记录结果中重复的记录(所有返回列的值都相同),只返回一条
语法:
SELECT DISTINCT 字段名1,字段名2... FROM 表名
注意:
ALL关键字是默认的,返回所有的记录,与之相反!
示例:
#查询成绩表中的所包含的课程ID
SELECT DISYINCT SubjectNo FROM result ;
数据库中的表达式
表达式一般由文本值、列值、NULL、函数和操作符等组成
应用场景:
SELECT 语句返回结果列中使用;
SELECT语句的ORDER BY 、HAVING 等子句中使用;
SELECT语句中的where条件语句中使用表达式
在SQL语句中使用表达式
A:在返回的列中使用,如:
SELECT version() , 100*3 #返回MySQL版本和计算结果
SELECT SubjectName “课程名称” , ClassHour+10 AS “新学时” FROM subject ;
#给返回结果中的课时都加10个课时
B:避免SQL返回结果中包含 . * ()等干扰
开发语言程序,如:
SELECT version() as MsSQL_V , 123.44 *100 AS EXPRESSION ;
#返回结果不会与后台开发程序发生混淆
用于检索数据表中符合条件的记录
搜索条件可由一个或多个逻辑表达式组成,结果一般为真或假
搜索条件的组成
逻辑操作符
比较操作符
DML(数据操作语言):
用于操作数据库对象中所包含的数据
包括:增删改查
添加数据语句: INSERT
更新数据语句: UPDATA
删除数据语句: DELETE
8. 添加数据
INSERT命令
语法:
INSERT INTO 表名 [( 字段1,字段2,字段3...)] VALUES (‘值1’, ‘值2’, ‘值3’,...)
注意:
示例:
#使用语句如何添加数据
INSERT INTO grade(gradename) VALUE ('大一');
/*INSERT INTO grade VALUE ('大一'); 错误示范--要改正:1.用自增的方法;2.用上一行的方法,给他明确的指示*/
INSERT INTO grade VALUE (2,'大二');
INSERT INTO grade(gradename) VALUE ('大三'),('大四');
9. 修改数据
UPDATE命令
语法:
UPDATE 表名 SET column_name=value [,column_name2=value2,... ] [ WHERE condition] ;
注意:
WHERE条件子句
简单理解为:
有条件地表中筛选数据
示例:
#使用语句修改数据
#将李四的地址修改为中国南京
UPDATE student SET address='中国南京'
筛选条件是:
WHERE studentname='李四'
WHERE student=1001
#同时修改多列时
UPDATE student SET address='中国南京' , email='[email protected]'
WHERE student=1001
#条件可以使用运算符
UPDATE student SET sex=1
WHERE studentno=1001 OR studentno=1002 OR studentno=1003
或者:
UPDATE student SET sex=1
WHERE studentno BETWEEN 1001 AND 1003
#使用函数
UPDATE student SET studentname=CONCAT("姓名:",studentname)
NOW()表示当前时间
#删除数据
DELETE FROM grade WHERE gradeid=4
一:DELETE命令
DELETE FROM 表名 [WHERE condition];
注意:
condition为筛选条件,如不指定则删除该表的所有列数据
二:TRUNCATE命令
TRUNCATE [TABLE] table_name
用于完全清空表数据,但表结构、索引、约束等不变
区别:
相同:
都能删除数据、不删除表结构,但是TRUNCATE速度更快
不同:
使用TRUNCATE TABLE重新设置AUTO_INCREMENT计数器
使用TRUNCATE TABLE不会对事物有影响
示例:
#该表表类型(存储引擎)InnoDB
CREATE TABLE test(
id INT(4) PRIMARY KEY AUTO_INCREMENT,
col VARCHAR(20) NOT NULL
)
INSERT INTO test(col) VALUE('row1'),('row2'),('row3');
#删除表的全部数据(不带WHERE条件的delete)
#自增的当前值是从原来的基础上进行/InnoDB
DELETE FROM test;
#删除表的全部数据(truncate)
#自增值会恢复到初始值重新开始/’MYISAM
TRUNCATE TABLE test;
#启动服务 net start mysql
#停止服务 net stop mysql
存储引擎的类型:
MyISAM,InnoDB,Memory,CSV等9种
常见的MyISAM与InnoDB类型主要区别
名称 |
MyISAM |
InnoDB |
事务处理 |
不支持 |
支持 |
数据行锁定 |
不支持 |
支持 |
外键约束 |
不支持 |
支持 |
全文索引 |
支持 |
不支持 |
表空间大小 |
较小 |
较大、约2倍 |
适用场合:
使用MyIASM:节约空间及相应速度较快;
使用InnoDB:安全性,可以用于事务处理及多用户操作数据表。
查看当前默认引擎
语法:
SHOW VARIABLES LIKE ‘strong_engine%’ ;
修改存储引擎
修改my.ini配置文件
default-storage-rngine=InnoDB---改为其他存储存储
语法:
CREATE TABLE 表名(
#省略代码
)ENGINE=存储引擎;
示例:
CREATE TABLE `myisam`(
id INT(4)
)ENGINE=MyISAM;
MyISAM类型表文件
*.frm:表结构定义文件
*.MYD:数据文件
*.MYI:索引文件
InnoDB类型表文件
*.frm:表结构定义文件
ibdata1文件
注意:
存储位置
因操作系统而异,可查my.ini
datadir="C:/ProgramData/MySQL/MySQL Server 5.5/Data/"
innodb_data_home_dir="D:/MySQL Datafiles/
语法:
INSERT INTO 表名 [(字段名列表)] VALUES (值列表);
注意:
字段名是可选的,如省略则依次插入所有字段
多个列表和多个值之间使用逗号分隔
值列表和字段名列表一一对应
如插入的是表中部分数据,字段名列表必填
示例:
INSERT INTO `student`(`loginPwd`,`studentName`,`gradeId`,`phone`,`bornDate`)
VALUES('123','黄小平',1,'13956799999','1996-5-8');
语法:
INSERT INTO 新表(字段名列表)
VALUES(值列表1),(值列表2),……,(值列表n);
示例:
INSERT INTO `subject`(`subjectName`,`classHour`,`gradeID`)
VALUES('Logic Java',220,1),('HTML',160,1),('Java OOP',230,2);
经验:
为避免表结构发生变化引发的错误,建议插入数据时写明具体字段名!
问题:
编写SQL语句实现从学生表提取姓名、手机号两列数据存储到通讯录表中
示例:
CREATE TABLE `phoneList`(
SELECT `studentName`,`phone`
FROM `student`);
如果新表以及存在,将会报错!
CREATE TABLE 新表(SELECT 字段1,字段2…… FROM 原表);
如果新表以及存在,不能重复创建。
例题:
编写SQL语句实现从学生表提取姓名、手机号两列数据存储到通讯录表中
答:
CREATE TABLE `phoneList`(
SELECT `studentName`,`phone`
FROM `student`);
更新数据记录:
语法:
UPDATE student SET sex=’女’ ;
UPDATE student SET address=’北京女子职业技术学校’
WHERE address=’北京女子武打院’ ;
删除数据记录
语法:
DELETE FROM 表名 [WHERE 条件] ;
TRUNCATE TABLE 表名 ;
TRUNCATE语句删除后将重置自增列,表结构及其字段、约束、索引保持不变,执行速度比DELETE语句块。
DELETE FROM student WHERE studentName = ‘王宝宝’;
TRUNCATE TABLE student;
UPDATE student SET email='[email protected]', loginPwd='000' WHERE studentNo=3
UPDATE `subject` SET subjectHour=subjectHour-10 WHERE subjectHour>200 AND gradeID=1
CREATE TABLE student_grade1(
SELECT studentName,sex,bornDate,phone
FROM student
);
MySQL中如何使用一条INSERT语句插入多条数据?
MySQL中将查询结果集插入新表的两种方式是什么?两者的区别是什么?
删除数据时使用DELETE和TRUNCATE的区别是什么?
#1. 将学号为3的学生的电话更改为131313131313
#2.
#3.
UPDATE student SET phone=1313131313 WHERE studentNo=3
UPDATE `subject` SET subjectName='文言文' WHERE subjectName='语文'
UPDATE `subject` SET subjectName="理科" WHERE subjectName="数学"
UPDATE result SET studentResult=studentResult+2 ;
UPDATE result SET studentResult=100 WHERE studentResult>100;
DELETE FROM student WHERE studentNo=1;
TRUNCATE TABLE student1;
DELETE FROM grade WHERE gradeId=1;
TRUNCATE TABLE grade;
查询产生一个虚拟表
看到的是表形式显示的结果,但结果并不真正存储
每次执行查询只是从数据表中提取数据,并按照表的形式显示出来
SELECT * FROM `student`
WHERE 所在班级 = 'S202'
SELECT <列名|表达式|函数|常量>
FROM <表名>
[WHERE <查询条件表达式>]
[ORDER BY <排序的列名>[ASC或DESC]];
示例:
SELECT `studentNo`,`studentName`,`phone`,`address`,`bornDate`
FROM `student`
WHERE `gradeId` = 1
ORDER BY `studentNo`;
查询全部的行和列
SELECT *FROM `student` ;
查询部分列
SELECT `studentNo` , `studentName` , `address`
FROM `student`
WHERE `address`=‘河南新乡’;
使用AS命名列
SELECT `studentNo` AS 学生编号,`studentName` AS 学生姓名,
`address `AS 学生地址
FROM `student`
WHERE `address` <> '河南新乡‘;
示例:
SELECT `firstName` + '.' + `lastName` AS 姓名
FROM `employees`;
注意:
1. + 连接的数据类型必须兼容
2. 如果 + 连接字符型数据,结果为字符串数据的连接
3. 如果 + 连接数值型数据,结果为数值的和
查询空行:
SELECT `studentName` FROM `student` WHERE `email` IS NULL;
原来有数据,单数数据被清除的列如何查询?
答:使用常量列!
示例:
SELECT `studentName` AS 姓名,`address` AS 地址,
’北京信息中心’ AS 学校名称
FROM `student`;
函数名 |
作用 |
AVG() |
返回某字段的平均值 |
COUNT() |
返回某字段的行数 |
MAX() |
返回某字段的最大值 |
MIN() |
返回某字段的最小值 |
SUM() |
返回某字段的和 |
函数名 |
作用 |
举例 |
CONCAT(str1, str1...strn) |
字符串连接
|
SELECT CONCAT('My','S','QL'); 返回:MySQL |
INSERT(str, pos,len, newstr)
|
字符串替换
|
SELECT INSERT( '这是SQL Server数据库', 3,10,'MySQL'); 返回:这是MySQL数据库 |
UPPER(str)
|
将字符串转为大写
|
SELECT UPPER('MySQL'); 返回:MYSQL |
LOWER(str) |
将字符串转为小写
|
SELECT LOWER('MySQL'); 返回:mysql |
SUBSTRING (str,num,len)
|
字符串截取
|
SELECT SUBSTRING( 'JavaMySQLOracle',5,5); 返回:MySQL |
SELECT CONCAT ('My','S','Q','L');
SELECT INSERT ('这是SQL Server数据库',3,10,'MySQL'); #数据库下标从1开始,这是从第三个开始替换。包括空格,一共替换10位
SELECT LOWER('MySQL'); #将字符串转为小写
SELECT UPPER('MySQL'); #将字符串转为大写
SELECT SUBSTRING('JavaMySQLOracle',5,5); #(str , num , len) 从下标是第五个开始截取,连续截取五位
SELECT CURTIME();
SELECT CURDATE();
SELECT NOW();
SELECT WEEK(NOW());
SELECT YEAR(NOW());
SELECT HOUR (NOW());
SELECT MINUTE (NOW());
SELECT DATEDIFF (NOW() , '2008-8-8');
SELECT ADDDATE (NOW(),4);
函数名 |
作用 |
举例 |
CEIL(x) |
返回大于或等于数值x的最小整数-取大值! |
返回大于或等于数值x的最小整数 |
FLOOR(x) |
返回小于或等于数值x的最大整数--取小值! |
SELECT FLOOR(2.3)-----------返回:2 |
RAND() |
返回0~1间的随机数 |
SELECT RAND() 返回:0.5525468583708134 |
SELECT CEIL(2.1);
SELECT FLOOR (2.9);
SELECT RAND();
SELECT RAND()+2;
ORDER BY子句实现按一定顺序显示查询结果
把成绩都降低10%后加5分,再查询及格成绩,并按照成绩从高到低排序
示例:
SELECT `studentNo` AS 学生编号,(studentResult*0.9+5 ) AS 综合成绩
FROM `result`
WHERE (`studentResult`*0.9+5) >=60
ORDER BY studentResult DESC;
MySQL查询语句中使用LIMIT子句限制结果集
语法:
SELECT <字段名列表>
FROM <表名或视图>
[WHERE <查询条件>]
[GROUP BY <分组的字段名>]
[ORDER BY <排序的列名>[ASC 或 DESC]]
[LIMIT [位置偏移量,]行数];
查询所有年级编号为1的学员信息,按学号升序排序
显示前4条记录
每页4条,显示第2页,即从第5条记录开始显示4条数据
示例:
SELECT `studentNo`,`studentName`,`phone`,`address`,`bornDate`
FROM `student`
WHERE `gradeId` = 1
ORDER BY studentNo
LIMIT 4;
SELECT `studentNo`,`studentName`,`phone`,`address`,`bornDate`
FROM `student`
WHERE `gradeId` = 1
ORDER BY studentNo
LIMIT 4;
LIMIT 4,4; --------------------从第5条开始显示4条
使用LIMIT子句时,注意第1条记录的位置是0!
编写SQL语句,查看年龄比“李斯文”小的学生,要求显示这些学生的信息
第一步:查询得到“李斯文”的出生日期
第二步:利用WHERE语句,筛选出生日期比“李斯文”大的学生
实现方法一:分两步实现
SELECT `bornDate` FROM `student` WHERE `studentName` = '李斯文';
SELECT `studentNo`, `studentName`,`sex`,`bornDate`,`address` FROM `student` WHERE bornDate > '1993-07-23';
实现方法二:采用子查询实现
SELECT `studentNo`,`studentName`,`sex`,`bornDate`,`address`
FROM `student`
WHERE `bornDate` >
(SELECT `bornDate` FROM `student` WHERE `studentName`='李斯文');
子查询是一个嵌套在 SELECT、INSERT、UPDATE 或 DELETE 语句或其他子查询中的查询
子查询在WHERE语句中的一般用法
语法:
SELECT … FROM 表1 WHERE 字段1 比较运算符(子查询)
注意:
将子查询和比较运算符联合使用,必须保证子查询返回的值不能多于一个
训练要点
使用子查询返回单条记录
需求说明
查询参加最近一次Logic Java考试成绩的学生的最高分和最低分
实现思路
查询获得“Logic Java”课程的课程编号
查询获得“Logic Java”课程最近一次的考试日期
根据课程编号查询考试成绩的最高分和最低分
SELECT MAX(`studentResult`) AS 最高分,
MIN(`studentResult`) AS 最低分
FROM `result`
WHERE `subjectNo`=
(SELECT `subjectNo` FROM `subject`
WHERE `subjectName`='Logic Java' ) AND
`examDate`=(SELECT MAX(`examDate`) FROM `result`
WHERE `subjectNo`=(SELECT `subjectNo` FROM `subject`
WHERE `subjectName`='Logic Java' ) );
between and ; like ; in ; null
查询姓李的同学的学号和姓名
like结合使用的通配符 % _
% ——0到任意个字符(数量)
_ ——1个字符
#找姓李的
SELECT stuno,stuname
FROM stu
WHERE stuname LIKE '李%';
#找姓李的,但是名字后面只有一个字
SELECT stuno.stuname
FROM stu
WHERE stuname LIKE '李_';
#找姓李的,但是名字后面有两个字
SELECT stuno ,stuname
FROM stu
WHERE stuname LIKE '李_ _'
#找姓名中有“文”这个字的同学
SELECT stuno ,stuname
FROM stu
WHERE stuname LIKE '%文%'
#查询学员姓名中有‘李’这个字的人的学号和姓名
SELECT stuno ,stuname
FROM stu
WHERE stunamelike '%李%';
#查询学员姓名中有‘%’这个字的人的学号和姓名 -----需要一个转义符 \
SELECT stuno ,stuname
FROM stu
WHERE stunamelike '% \% %';
#转义符是\ ,能不能使用我自己喜欢的当作转义符呢? ---可以! 但是要用ESCAPE方法
SELECT stuno ,stuname
FROM stu
WHERE stunamelike '% :% %' ESCAPE ':';
SELECT stuno ,stuname
FROM stu
WHERE stuno IN (1000,1001,1002,1003,1004,1005);
SELECT stuno ,stuname
FROM stu
WHERE stuno IN (北京,武汉,南京,上海);
#NULL 空
#查询出生日期没有填写的同学 ( IS NULL是对的 = NULL这个写法是错的)
SELECT stunanme
FROM stu
WHERE borndate IS NULL;
#查询出生日期填写过了的同学 ( IS NULL是对的 = NULL这个写法是错的)
SELECT stunanme
FROM stu
WHERE borndate IS NOT NULL;
#区别空字符串 和 NULL
SELECT * FROM stu ;
#查询家庭地址没有写的同学
SELECT stunanme
FROM stu
WHERE address IS NULL;
#查询家庭地址写了但是被删空了,现在是空字符串的同学
SELECT stunanme
FROM stu
WHERE address='';
#实际应用中,需要把上面两种情况都考虑到,用OR连接 address IS NULL address=''
利用关系,把所需要的两个表或者多个表连接起来的查询出来一个结果。
SELECT语法:
#连接查询
#内连接 ------inner join
#外连接 ------outer join
#左外连接 left [outer] join
#右连接 right [outer] join
#左连接:以左表作为基准,右边表来一一匹配,匹配不上的,返回左表的记录,右表则用NULL填充
#右连接:以右表作为基准,左边表来一一匹配,匹配不上的,返回右表的记录,左表则用NULL填充
#自连接
#等值连接 非等值连接
#查询参加了考试的同学信息(学号,姓名 科目编号,分数)
SELECT *FROM stu;
SELECT *FROM result;
#(1)思路:分析需求,确定查询的列,来源于哪?两个表?! 再连接查询
#(2)再确定使用哪一种连接查询? ---内连接--取决条件不再是where,而是ON--当表连接成立的条件
SELECT stu.studentNo ,stuname.subjectno,sturesult
FROM stu INNER JOIN result
ON result.studentNo=stu.studentNo
#取别名之后的样式
SELECT s.studentNo ,stuname.subjectno,sturesult
FROM stu s
INNER JOIN result r
ON r.studentNo=s.studentNo
#左连接
SELECT s.studentNo ,stuname.subjectno,sturesult
FROM stu s
LEFT JOIN result r
ON r.studentNo=s.studentNo
#右连接
SELECT s.studentNo ,stuname.subjectno,sturesult
FROM stu s
RIGHT JOIN result r
ON r.studentNo=s.studentNo
#查一下缺考的同学
SELECT stuname
FROM stu s
LEFT JOIN result r
ON r.studentNo=s.studentNo
WHERE sturesult IS NULL;
#等值连接 非等值连接的区别是有没有WHERE条件
#等值连接 (结果、效果和内连接一样)
SELECT s.studentNo ,stuname.subjectno,sturesult
FROM stu s , result r
WHERE r.studentNo=s.studentNo
#非等值连接 ---不加where条件
SELECT s.studentNo ,stuname.subjectno,sturesult
FROM stu s , result r
#自连接:
#连接查询(自连接)
CREATE TABLE IF NOT EXISTS category(
categoryid INT (10) UNSIGNED NOT NULL AUTO_INCREMENT,
pid INT (10) NOT NULL ,
categoryName VARCHAR(50) NOT NULL ,
PRIMARY KEY (categoryid)
)
INSERT INTO category
VALUES(2,1,"美术设计"),
(3,1,"软件开发"),
(4,3,"数据库基础"),
(5,2,"ps基础"),
(6,2,"色彩搭配"),
(7,3,"PHP基础"),
(8,3,"Java基础");
#编写SQL语句,将栏目的父子关系呈现出来(父栏目名称,子栏目名称)
#父栏目 子栏目
# 1 5,6
# 2 4,7,8
#把category表看作两张一模一样的表,然后将这两张表连接查询 (自连接)
SELECT a.categoryName AS '父栏目',b.categoryName AS '子栏目'
FROM category AS a,category AS b
WHERE a.categoryid=b.pid
SELECT * FROM category;
#多重多行--难度升级版
#多重
#查询参加过考试的同学的信息()
SELECT s.studentno,studentname,subjectname,studentresult
FROM student s
INNER JOIN result r
ON s.StudentNo=r.StudentNo
INNER JOIN `subject` sub
ON r.SubjectNo=sub.subjectno
#1.查询学员,以及所属的年级(学号、学生姓名、年级名) 1 张三 大一
#学号、学生姓名---学生表里; 年级名----年级表里
SELECT studentno AS '学号',studentname AS '学生姓名',gradename AS 年级名称
FROM student
INNER JOIN grade
ON student.GradeId=grade.GradeID
#2.查询科目及所属的年级(科目名称、年级名称) java 大一 ; ps 大二
#年级名称---grade表 ;科目名称 ----subject表
SELECT subjectname AS 科目名称 ,gradename 年级名称
FROM `subject` sub
INNER JOIN grade g
ON sub.gradeid=g.gradeid
#查询《数据库结构-1》的所有人的考试结果(学号、学生姓名、科目名称、成绩)
#然后,再按成绩由高到低降序排列
#默认 ASC 升序 ; DESC 降序
SELECT stuid , stuname,subname,sturesult
FROM stu s
INNER JOIN result r
ON s.studentNo=r.studentNo
INNER JOIN `subject` sub
ON r.subjectNo=sub.subjectNo
WHERE subjectname='数据库结构-1'
ORDER BY sturesult DESC ,stuno #相同的按照第二种排序(默认升序)
#常见错误:ORDER BY studentresult , studentno DESC 正确含义:成绩升序排列,相同的成绩再降序排列
#分页一定会用到 --(用户体验、网络传输、查询压力)
#查询《数据库结构-1》的所有人的考试结果(学号、学生姓名、科目名称、成绩),然后,再按成绩由高到低降序排列
#每页显示5条记录出来
SELECT stuid , stuname,subname,sturesult
FROM stu s
INNER JOIN result r
ON s.studentNo=r.studentNo
INNER JOIN `subject` sub
ON r.subjectNo=sub.subjectNo
WHERE subjectname='数据库结构-1'
ORDER BY sturesult DESC
#limit 0,5; #等同于 limit 5 offset 0;
LIMIT 5 OFFSET 0;
#limit 0,5; #第一页
#0:从哪条记录开始(起始行) 5:要显示几行 数据库的下标是从0开始!!!
#LIMIT 5,5; #第二页
#limit 10,5 #第三页
#limit a,b
# 数字规律是:(a-1)*b , b (当前页码-1)*页容量 , 页容量
#实战检测!
#查询 《JAVA第一学年》 课的前10名的成绩,且分数大于80的学生的信息(学号、姓名、课程名、分数)
SELECT s.studentno,studentname ,subjectname ,studentresult
FROM student s
INNER JOIN result r
ON s.studentNo=r.studentNo
INNER JOIN `subject` sub
ON r.subjectNo=sub.subjectNo
WHERE subjectname='JAVA第一学年'AND studentresult >80
ORDER BY studnetresult DESC
LIMIT 0,10;
查询“Logic Java”课程考试成绩为60分的学生名单
解决方法:采用 IN 子查询
SELECT `studentName` FROM `student`
WHERE `studentNo` IN( #将=号改为IN
SELECT `studentNo` FROM `result`
WHERE `subjectNo` = (
SELECT `subjectNo` FROM `subject`
WHERE `subjectName`='Logic Java'
)AND `studentResult` = 60
);
常用IN替换等于(=)的子查询
IN后面的子查询可以返回多条记录
查询参加“Logic Java”课程最近一次考试的在读学生名单
实现步骤:
SELECT `subjectNo` FROM `subject`
WHERE `subjectName`='Logic Java';
SELECT MAX(`examDate`) FROM `result` WHERE `subjectNo`= (
SELECT `subjectNo` FROM `subject`
WHERE `subjectName`='Logic Java' );
3.根据课程编号和最近一次的考试日期查询出在读学生信息
参考语句:
问题:
查询未参加“Logic Java”课程最近一次考试的在读学生名单
SELECT `studentNo`, `studentName` FROM `student` WHERE `studentNo`
NOT IN(
SELECT `studentNo` FROM `result`
WHERE `subjectNo` = (
SELECT `subjectNo` FROM `subject`
WHERE `subjectName`='Logic Java'
) AND `examDate` = (
SELECT MAX(`examDate`) FROM `result` WHERE `subjectNo` = (
SELECT `subjectNo` FROM `subject`
WHERE `subjectName`='Logic Java')
)
)……
实现思路
查询获得年级名称是S1的所有课程的课程编号
根据课程编号查询课程表得到课程名称
SELECT `subjectName` FROM `subject` WHERE `gradeId` IN (
SELECT `gradeId` FROM `grade` WHERE `gradeName`='S1'
)
SELECT `studentName` FROM `student`
WHERE `studentNo` NOT IN (
SELECT `studentNo` FROM `result`
WHERE `subjectNo` = (
SELECT `subjectNo` FROM `subject`
WHERE `subjectName`='HTML'
)
AND `examDate` = (
SELECT MAX(`examDate`) FROM `result`
WHERE `subjectNo` =(
SELECT `subjectNo` FROM `subject`
WHERE `subjectName`='HTML' )
))
AND `gradeId` = (
SELECT `subjectNo` FROM `subject`
WHERE `subjectName`='HTML'
);
实例:
#查询所有学生信息 * 所有列,效率低
SELECT * FROM student;
#查询指定列(学号、姓名)
SELECT studentno,studentname FROM student;
#给列取别名 (AS可以省略)
SELECT studentno AS 学号,studentname AS 姓名 FROM student;
SELECT studentno 学号,studentname 姓名 FROM student;
#使用AS也可以给表取别名 (AS可以省略)
SELECT studentno 学号,studentname 姓名 FROM student AS bm;
SELECT studentno 学号,studentname 姓名 FROM student bm;
#使用AS ,为查询结果取一个新名字
SELECT CONCAT ('姓名:'studentname) AS 新姓名 FROM student;
#查看考试成绩
SELECT * FROM result ;
#查看哪些人参加了考试(学号)--去除重复项-distinct , 默认的是all
SELECT DISTINCT studentno FROM result ;
#select 查询中可以使用表达式
SELECT @@auto_increment_increment ----查询步长
SELECT VERSION (); --查询版本号
SELECT 100*3-1; ---查询计算结果 SELECT 100*3-1 AS 计算结果 ;
#学员考试成绩,集体加分,+1
SELECT studentno , studentresult+1 AS '加分后' FROM result ;
#满足条件的查询 (WHERE)