MySQL数据管理

  1. 外键管理

外键作用

创建外键:

建表是指定外键约束

建表后修改

删除外键

删除外键、删除表

 

  1. 添加主键约束

语法:

ALTER TABLE 表名 ADD CONSTRAINT 主键名

         PRIMARY KEY 表名(主键字段);

问题:

如何设置grade表中gradeId字段为主键?

ALTER TABLE `grade` ADD CONSTRAINT `pk_grade`  

PRIMARY KEY `grade`(`gradeId`);

 

  1. 添加外键

语法:

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`);

 

  1. #创建外键方式一:创建子表的同时创建外键

 

#年级表(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)

);

 

  1. #创建外键方式二:创建子表完毕后,修改子表、添加外键

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 ;

 

  1. 数据库管理:

数据库意义:
数据存储;

数据管理。

管理数据库数据方法:

通过SQLyog等管理工具管理数据库数据;

通过DML语句管理数据库数据。

 

  1. DQL语言--DQL数据查询语言
  1. 查询数据库,如SELECT语句
  2. 简单的单表查询或多表的复杂查询和嵌套查询
  3. 数据库语言中最核心、最重要的语句
  4. 使用频率最高的语句

 

  1. SELECT语法:

SELECT* FROM 表名

指定查询字段:

查询表结果时,可指定查询结果的数据

查询表中所有的数据结果,采用 *  符号;

例如:

select * from student ;   ------------效率低,不推荐

可指定查询的结果数据列:

如只查询student表中的学号、姓名、电话:

SELECT StudentNo,StudentName,Phone  FROM student ;

如区分连接查询时两个表有同名的字段:

SELECT student.StudentNo,StudentName,StudentResult  FROM student , result ;

----可指定该字段属于哪个表

       

  1. AS子句作为别名

AS子句作用:

  1. 可给数据列取一个新别名
  2. 可给表去一个新别名
  3. 可把经过计算或总结的结果用另一个新名称来代替

AS子句用法

如:

SELECT StudentNo AS “学号” FROM student ;

SELECT a.StudentNo FROM student AS a ;

SELECT Phone+1 AS Tel FROM student ;

------AS也可以省略不写

 

  1. DISTINCT关键字的使用

DISTINCT关键字

作用:

去掉SELECT查询返回的记录结果中重复的记录(所有返回列的值都相同),只返回一条

语法:

SELECT DISTINCT 字段名1,字段名2... FROM 表名

注意:

ALL关键字是默认的,返回所有的记录,与之相反!

示例:

#查询成绩表中的所包含的课程ID

SELECT DISYINCT SubjectNo FROM result ;

  1. 使用表达式的列-1

数据库中的表达式

表达式一般由文本值、列值、NULL、函数和操作符等组成

应用场景:

SELECT 语句返回结果列中使用;

SELECT语句的ORDER BY 、HAVING 等子句中使用;

SELECT语句中的where条件语句中使用表达式

  1. 使用表达式的列-17

在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 ;

#返回结果不会与后台开发程序发生混淆

  1. WHERE条件语句

用于检索数据表中符合条件的记录

搜索条件可由一个或多个逻辑表达式组成,结果一般为真或假

搜索条件的组成

逻辑操作符

比较操作符

  1. 逻辑运算符

  1. 比较操作符

  1. 逻辑操作符

  1. DML语言

DML(数据操作语言):

用于操作数据库对象中所包含的数据

包括:增删改查

添加数据语句: INSERT

更新数据语句: UPDATA

删除数据语句: DELETE

 

8. 添加数据

INSERT命令

语法:

INSERT INTO 表名 [( 字段1,字段2,字段3...)] VALUES (值1, 值2, 值3,...)

注意:

  1. 字段或值之间用英文逗号隔开
  2. “字段1”,“字段2”.。。该部分可以省略,但是添加的值必须和表结构数据列顺序相对应,且数量一致
  3. 可同时插入多条数据,values后面用英文逗号隔开

示例:

#使用语句如何添加数据

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] ;

注意:

  1. column_name为要更改的数据列
  2. value为修改后的数据,可以为变量、具体值、表达式或者嵌套的SELECT结果
  3. 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

 

  1. 删除数据

一: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

  1. MySQL的存储引擎

存储引擎的类型:

MyISAM,InnoDB,Memory,CSV等9种

常见的MyISAM与InnoDB类型主要区别

名称

MyISAM

InnoDB

事务处理

不支持

支持

数据行锁定

不支持

支持

外键约束

不支持

支持

全文索引

支持

不支持

表空间大小

较小

较大、约2倍

 

适用场合:

使用MyIASM:节约空间及相应速度较快;

使用InnoDB:安全性,可以用于事务处理及多用户操作数据表。

 

  1. MySQL的存储引擎

查看当前默认引擎

语法:

SHOW VARIABLES LIKE strong_engine% ;

修改存储引擎

修改my.ini配置文件

default-storage-rngine=InnoDB---改为其他存储存储

  1. 设置表的存储引擎

语法:

CREATE TABLE 表名(

#省略代码

ENGINE=存储引擎;

示例:

CREATE TABLE `myisam`(

id INT(4)

)ENGINE=MyISAM;

  1. 数据表的存储位置

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/

  1. DML语句——插入单条数据记录

语法:

INSERT INTO 表名 [(字段名列表)] VALUES (值列表);

注意:

字段名是可选的,如省略则依次插入所有字段

多个列表和多个值之间使用逗号分隔

值列表和字段名列表一一对应

如插入的是表中部分数据,字段名列表必填

示例:

INSERT INTO `student`(`loginPwd`,`studentName`,`gradeId`,`phone`,`bornDate`)

VALUES('123','黄小平',1,'13956799999','1996-5-8');

 

  1. DML语句——插入多条数据记录

语法:

 INSERT INTO 新表(字段名列表)

 VALUES(值列表1),(值列表2),……,(值列表n);

示例:

INSERT INTO `subject`(`subjectName`,`classHour`,`gradeID`)

VALUES('Logic Java',220,1),('HTML',160,1),('Java OOP',230,2);

经验:

为避免表结构发生变化引发的错误,建议插入数据时写明具体字段名!

 

  1. DML语句——将查询结果插入新表

问题:

编写SQL语句实现从学生表提取姓名、手机号两列数据存储到通讯录表中

示例:

CREATE TABLE `phoneList`(

    SELECT `studentName`,`phone`

    FROM `student`);

如果新表以及存在,将会报错!

  1. 将查询结果插入新表

  CREATE TABLE 新表(SELECT 字段1,字段2……  FROM 原表);

如果新表以及存在,不能重复创建。

例题:

编写SQL语句实现从学生表提取姓名、手机号两列数据存储到通讯录表中

答:

CREATE TABLE `phoneList`(

SELECT `studentName`,`phone`

FROM `student`);

 

  1. 数据更新

更新数据记录:

语法:

UPDATE student SET sex=’女’ ;

UPDATE student SET address=’北京女子职业技术学校’

WHERE address=’北京女子武打院’ ;

  1. 数据删除

删除数据记录

语法:

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

);

  1. 小结

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;

  1. 什么是查询?

查询产生一个虚拟表

看到的是表形式显示的结果,但结果并不真正存储

每次执行查询只是从数据表中提取数据,并按照表的形式显示出来

 

  1. 查询机制简介

SELECT * FROM `student`

WHERE 所在班级 = 'S202'

  1. 查询语法

SELECT    <列名|表达式|函数|常量>

FROM      <表名>

[WHERE    <查询条件表达式>]

[ORDER BY <排序的列名>[ASC或DESC]];

示例:

SELECT `studentNo`,`studentName`,`phone`,`address`,`bornDate`

FROM `student`

WHERE `gradeId` = 1

ORDER BY `studentNo`;

 

  1. 数据查询基础

查询全部的行和列

SELECT *FROM `student` ;

查询部分列

SELECT `studentNo` , `studentName` , `address`

FROM `student`

WHERE `address`=‘河南新乡’;

 

  1. 数据查询-列别名

使用AS命名列

SELECT `studentNo`  AS 学生编号,`studentName` AS 学生姓名,

        `address `AS 学生地址  

FROM `student`

WHERE `address` <> '河南新乡‘;

示例:

SELECT `firstName` + '.' + `lastName` AS 姓名

FROM `employees`;

注意:

1.  + 连接的数据类型必须兼容

2. 如果 + 连接字符型数据,结果为字符串数据的连接

3. 如果 + 连接数值型数据,结果为数值的和

 

  1. 数据查询-空行、常量列  PPT第22页开始!  

查询空行:

SELECT `studentName` FROM `student` WHERE `email` IS NULL;

原来有数据,单数数据被清除的列如何查询?

答:使用常量列!

示例:

SELECT `studentName` AS 姓名,`address` AS 地址,

’北京信息中心’ AS 学校名称

FROM `student`;

 

  1. 常用函数——聚合函数

函数名

作用

AVG()

返回某字段的平均值

COUNT()

返回某字段的行数

MAX()

返回某字段的最大值

MIN()

返回某字段的最小值

SUM()

返回某字段的和

 

  1. 常数函数----字符串函数

函数名

作用

举例

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) 从下标是第五个开始截取,连续截取五位

 

  1. 常用函数——时间日期函数

   

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);

  1. 常用函数——数学函数

函数名

作用

举例

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;

  1. ORDER BY子句

ORDER BY子句实现按一定顺序显示查询结果

把成绩都降低10%后加5分,再查询及格成绩,并按照成绩从高到低排序

示例:

SELECT `studentNo` AS 学生编号,(studentResult*0.9+5 ) AS 综合成绩

FROM `result`

WHERE (`studentResult`*0.9+5) >=60

ORDER BY studentResult DESC;

 

  1. LIMIT子句2-1

MySQL查询语句中使用LIMIT子句限制结果集

语法:

SELECT  <字段名列表>

FROM  <表名或视图>

[WHERE  <查询条件>]

[GROUP BY <分组的字段名>]

[ORDER BY  <排序的列名>[ASC 或 DESC]]

[LIMIT [位置偏移量,]行数];

 

  1. LIMIT子句2-2

查询所有年级编号为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!

 

  1. 什么是子查询3-1

编写SQL语句,查看年龄比“李斯文”小的学生,要求显示这些学生的信息

第一步:查询得到“李斯文”的出生日期

第二步:利用WHERE语句,筛选出生日期比“李斯文”大的学生

  1. 什么是子查询3-2

实现方法一:分两步实现

  1. 查找出“李斯文”的出生日期

SELECT `bornDate` FROM `student` WHERE `studentName` = '李斯文';

  1. 利用WHERE语句筛选出生日期比“李斯文”大的学生

SELECT `studentNo`, `studentName`,`sex`,`bornDate`,`address` FROM `student` WHERE bornDate > '1993-07-23';

 

  1. 什么是子查询3-3

实现方法二:采用子查询实现

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  比较运算符(子查询)

注意:

将子查询和比较运算符联合使用,必须保证子查询返回的值不能多于一个

 

  1. 操作——查询指定学生成绩2-1

训练要点

使用子查询返回单条记录

需求说明

查询参加最近一次Logic Java考试成绩的学生的最高分和最低分

 

  1. 操作——查询指定学生成绩2-2

实现思路

查询获得“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' ) );

 

  1. 比较操作符

  1. 模糊查询 --like  %  _

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 ':';

  1. 模糊查询   ----IN

SELECT stuno ,stuname

FROM stu

WHERE stuno IN (1000,1001,1002,1003,1004,1005);

 

SELECT stuno ,stuname

FROM stu

WHERE stuno IN (北京,武汉,南京,上海);

 

  1. 模糊查询  ---NULL

#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=''

 

  1. 连接查询

利用关系,把所需要的两个表或者多个表连接起来的查询出来一个结果。

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;

  1. IN子查询4-1

查询“Logic Java”课程考试成绩为60分的学生名单

解决方法:采用 IN 子查询

 

  1. IN子查询4-2

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后面的子查询可以返回多条记录

 

  1. IN子查询4-3

查询参加“Logic Java”课程最近一次考试的在读学生名单

实现步骤:

  1. 获得 “Logic Java”课程的课程编号

SELECT `subjectNo` FROM `subject`

 WHERE `subjectName`='Logic Java';

  1. 根据课程编号查询得到“Logic Java”课程最近一次的考试日期

SELECT MAX(`examDate`) FROM `result` WHERE `subjectNo`= (

SELECT `subjectNo` FROM `subject`

WHERE `subjectName`='Logic Java' );

3.根据课程编号和最近一次的考试日期查询出在读学生信息

 

  1. IN子查询4-4

参考语句:

  1. NOT IN子查询

问题:

查询未参加“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')

   )

)……

 

  1. 操作——查询某学期开设的课程

实现思路

查询获得年级名称是S1的所有课程的课程编号

根据课程编号查询课程表得到课程名称

SELECT `subjectName` FROM `subject` WHERE `gradeId` IN (

       SELECT `gradeId` FROM `grade` WHERE `gradeName`='S1'

)

 

  1. 操作——查询最近一次考试缺考学生

   

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'

);

 

  1. 总结

 

 

实例:

#查询所有学生信息      * 所有列,效率低

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)

 

发布了65 篇原创文章 · 获赞 15 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/kxindouhao5491/article/details/82831277