一、1.MySQL的存储引擎

储存引擎的类型:MyISAM、InnoDB、 Memory、CSV等九种

MyiSAM和InnoDB类型主要区别

名称

InnoDB

MyISAM

事务处理

支持

不支持

数据行锁定

支持

不支持

外键约束

支持

不支持

全文索引

不支持

支持

表空间大小

较大,约2倍

较小

适用场合

<1>使用MyISAM:不需事务,空间小,以查询访问为主

<2>使用InnoDB:多删除,更新操作, 安全性高,事务处理及并发控制

2.查看当前默认储存引擎

语法:SHOW VARIABLES LIKE'storage_engine%':

执行命令得

mysql 按年 group by mysql按年份分组_mysql 按年 group by

修改存储引擎  

    修改my.ini配置文件

语法:default-storage-engine=InnoDB(改为其他存储存储)

设置表的存储引擎 

语法:CREATE TABLE 表名(#省略代码)ENGINE=存储引擎;

CREATE TABLE test_mysam(
	tit INT
	)ENGINE=MYISAM;

执行命令得

mysql 按年 group by mysql按年份分组_子查询_02

默认为InnoDB存储引擎  两个引擎的不同 会使表中存储数据时的格式不同

3.数据表的存储位置

<1>MyISAM类型表文件

    *.frm:表结构定义文件

    *.MYD:数据文件

    *.MYI:索引文件

<2>InnoDB类型表文件

  *.frm:表结构定义文件

    ibdata1文件

注意!!!

存储位置 (因操作系统而异,可查my.ini)

二、DML语句

 Data Manipulation Language,数据操纵语言,命令使用户能够查询数据库以及操作已有数据库中的数据的计算机语言。具体是指是SELECT查询、UPDATE更新、INSERT插入、DELETE删除。

1.插入单条数据纪录

语法:INSERT IN TO 表名 (字段名列表) VALUES (值列表);

注意!!!

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

    <2>多个列表和多个值之间是用逗号隔开

    <3>值列表和字段名列表一一对应

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

例:

USE python7;
INSERT INTO `student`(`studentNo`,`loginPwd`,`studentName`,`gradeId`,`phone`,`bornDate`)
VALUES(30013,'123','黄小平',1,'13956799999','1996-5-8');

执行命令得

mysql 按年 group by mysql按年份分组_Java_03

2.插入多调数据记录

语法:INSERT INTO 新表(字段名列表)

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

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

例:

CREATE TABLE SUBJECT(
	subjectNo INT(4) PRIMARY KEY AUTO_INCREMENT,
	subjectName VARCHAR(50),
	classHour INT(4),
	gradeID INT(4)
	)
INSERT INTO `subject`(`subjectName`,`classHour`,`gradeID`)
VALUES('Logic Java',220,1),('HTML',160,1),('Java OOP',230,2);

执行命令得

mysql 按年 group by mysql按年份分组_mysql 按年 group by_04

3.将查询结果插入新表

语法:CREATE TABLE  新表( SELECT (值列表1),值列表2)...(值列表n)  FROM 旧表);

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

方法一:如果新列表已经存在将会报错

CREATE TABLE phoneList(
	SELECT studentName,phone FROM student
	);

方法二:phoneList必须存在 其中列的数据类型和原表的数据类型一致

给表添加新增列:先给表添加主键然后属性为新增

mysql 按年 group by mysql按年份分组_字段_05

CREATE TABLE phoneList(
	studentName VARCHAR(50) NOT NULL,
	phone VARCHAR(50) DEFAULT NULL)
INSERT INTO phoneList()
SELECT
studentName,phone
FROM student

执行命令得

mysql 按年 group by mysql按年份分组_Java_06

4.数据更新

语法:UPDATE 表名 

SET 字段1=值1 , 字段2=值2,...,字段n=值n

[WHERE 条件]

例:

UPDATE student SET sex='男';
#不添加条件则全部变为男性
UPDATE student SET gradeID=3,loginPwd=123456#年级编号 密码改变
WHERE studentNo>20010#条件为学号>20010的学生

执行命令得

mysql 按年 group by mysql按年份分组_mysql 按年 group by_07

5.数据删除

语法:DELETE FROM 表名 [WHERE 条件];

TRUNCATE TABLE 表名;

(TRUNCATE语句删除后将重置自增列,表结构及其字段、约束、索引保持不变,执行速度比DELETE语句块)

例:

DELETE FROM phoneList
WHERE studentName='郭靖'#删除名为郭靖的行

执行命令得

mysql 按年 group by mysql按年份分组_Java_08

三、查询

mysql 按年 group by mysql按年份分组_Java_09

查询产生一个虚拟表

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

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

1.查询全部的行和列

语法:SELECT * FROM student

2.查询部分列

语法:SELECT `studentNo`,`studentName`,`address`

FROM `student`

WHERE `address='天津市河西区'`

3.使用AS命名列

SELECT `studentNo`  AS' 学生编号',`studentName` AS '学生姓名',
        `address `AS 学生地址  
FROM `student`

WHERE `address` ='天津市河西区';

代码:

SELECT studentNo AS '学号',studentName AS '姓名',phone AS '手机',address AS '地址',bornDate AS '出生日期'
FROM `student`
WHERE gradeID=1#条件为班级编号1的学生

执行命令得

mysql 按年 group by mysql按年份分组_子查询_10

4.查询空行

语法:SELECT `studentName` FROM `student` WHERE `email` IS NULL;

代码

UPDATE student SET email=666
WHERE loginPwd=123
SELECT `studentName` FROM `student` WHERE `email` IS NULL;

执行代码得

mysql 按年 group by mysql按年份分组_mysql 按年 group by_11

使用常量列

为每条数据添加一个常量列

SELECT *,'北京信息中心' AS '学校名称' FROM `student`
WHERE gradeID>1

执行命令得

mysql 按年 group by mysql按年份分组_MySQL_12

四、常用函数

1.聚合函数

函数名

作用

AVG()

返回某字段的平均值

COUNT()

返回某字段的行数

MAX()

返回某字段的最大值

MIN()

返回某字段的最小值

SUM()

返回某字段的和

:

SELECT AVG(`studentResult`) AS '平均成绩',
		COUNT(*) AS '参加人数',
		MAX(studentResult) AS '最高',
		MIN(studentResult) AS '最低',
		SUM(studentResult) AS '总和'
		
FROM result

执行命令得

mysql 按年 group by mysql按年份分组_MySQL_13

2.字符串函数

函数名

作用 

举例

CONCAT(str1,str1...strn)

字符串连接

SELECT    CONCAT('My','S','QL');
返回:MySQL

INSERT(str,pos,len,newstr)

字符串替换

SELECT INSERT(
    '这是SQL Server数据库',
    3,10,'MySQL');
返回:这是MySQL数据库

LOWER(str)

将字符串转为小写

SELECT LOWER('MySQL');
返回:mysql

UPPER(str)

将字符串转为大写

SELECT UPPER('MySQL');
 返回:MYSQL

SUBSTRING(str,num,len)

字符串截取

SELECT SUBSTRING(
    'JavaMySQLOracle',5,5);
返回:MySQL

例:

#字符串连接
SELECT CONCAT('北','京','海','淀');
#字符串替换 (原,开始,长度,新)
SELECT INSERT('北京市',1,2,'运城');
#替换大小写
SELECT LOWER('Hello');
SELECT UPPER('Hello');
#字符串截取
SELECT SUBSTRING('hello mysql',7,5)

分别执行命令的

mysql 按年 group by mysql按年份分组_MySQL_14

mysql 按年 group by mysql按年份分组_Java_15

mysql 按年 group by mysql按年份分组_mysql 按年 group by_16

mysql 按年 group by mysql按年份分组_MySQL_17

mysql 按年 group by mysql按年份分组_Java_18

3.时间日期函数

函数名

作用

举例(结果与当前时间有关)

CURDATE()

获取当前日期

SELECT CURDATE();
返回:2016-08-08

CURTIME()

获取当前时间

SELECT CURTIME();
返回:19:19:26

NOW()

获取当前日期和时间

SELECT NOW();
返回:2016-08-08 19:19:26

WEEK(date)

返回日期date为一年中的第几周

SELECT WEEK(NOW());
返回:26

YEAR(date)

返回日期date的年份

SELECT YEAR(NOW());
返回:2016

HOUR(time)

返回时间time的小时值

SELECT HOUR(NOW());
返回:9

MINUTE(time)

返回时间time的分钟值

SELECT MINUTE(NOW());
返回:43

DATEDIFF(date1,date2)

返回日期参数date1和date2之间相隔的天数

SELECT DATEDIFF(NOW(),
     '2008-8-8');
返回:2881    

ADDDATE(date,n)

计算日期参数date加上n天后的日期

SELECT ADDDATE(NOW(),5);
返回:2016-09-02  09:37:07

例:

SELECT CURDATE()#获取当前日期
SELECT CURTIME()#获取当前时间
SELECT NOW()#获取当前日期和时间
SELECT WEEK(NOW())#返回日期为一年中的第几周
SELECT YEAR(NOW())#返回日期的年份
SELECT HOUR(NOW())#返回时间的小时数
SELECT MINUTE(NOW())#返回时间的分钟数
SELECT DATEDIFF(NOW(),'2020-8-8')#返回两个日期之间的相隔的天数
SELECT ADDDATE(NOW(),100)#计算日期参数now加上100天后的日期

4.数学函数

函数名

作用

举例

CEIL(x)

返回大于或等于数值x的最小整数

SELECT CEIL(2.3)
返回:3

FLOOR(x)

返回小于或等于数值x的最大整数

SELECT FLOOR(2.3)
返回:2

RAND()

返回0-1的随机数

SELECT RAND()
返回:0.5525468583708134

例:

SELECT CEIL(2.3)#返回大于或等于数值为2.3的最小整数
SELECT FLOOR(2.3)#返回小于或等于数值为2.3的最大整数
SELECT RAND()#返回0-1之间的随机数



五、1.ORDER BY子句

ORDER BY 子句实现按一定顺序显示查询结果(ASC:升序  DESC:降序)

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

SELECT studentNo AS '学生编号',`studentResult`*(1-0.1)+5 AS '综合成绩'
FROM `result`
WHERE `studentResult`*(1-0.1)+5>=60
ORDER BY `studentResult` DESC

执行命令得

mysql 按年 group by mysql按年份分组_字段_19

2.LIMIT子句

MySQL查询语句中使用LIMIT子句限制结果集 (做分页)

语法:SELECT  <字段名列表>
FROM  <表名或视图>
[WHERE  <查询条件>]
[GROUP BY <分组的字段名>]
[ORDER BY  <排序的列名>[ASC 或 DESC]]

[LIMIT [位置偏移量,]行数];   /    LIMIT ((页数-1)*条数),条数;

例如:

SELECT studentNo AS '学生编号',`studentResult`*(1-0.1)+5 AS '综合成绩'
FROM `result`
WHERE `studentResult`*(1-0.1)+5>=60
ORDER BY `studentResult` DESC
LIMIT 2,3#从数据的第二行开始读取三行

执行命令得 

mysql 按年 group by mysql按年份分组_字段_20

练习:

查询所有年级密码为123的学员信息,按学号升序排序

显示每页2条

显示第2页,即从第3条数据开始显示2条数据

SELECT studentNo AS '学生编号',`studentName` AS '姓名',`phone` AS '电话'
FROM `student`
WHERE `loginPwd`=123
ORDER BY `studentNo`
LIMIT 2,2

执行命令得

不加LIMIT句子

mysql 按年 group by mysql按年份分组_MySQL_21

加上LIMIT句子

mysql 按年 group by mysql按年份分组_子查询_22

3.子查询

子查询是一个潜逃在SELECT 、INSERT、UPDATE、或DELETE语句或其他子查询中的查询

子查询在WHERE语句中的一般用法

语法:SELECT...FROM 表名 WHERE 字段 比较运算符 (子查询)

注意:

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

例:编写SQL语句,查看年龄比'黄小平'晓得学生,要求显示这些学生的信息

分析:

第一步:查询得到'黄小勇'的出生日期

第二步:利用where语句,筛选出生日期比'黄小平'大的学生

(此方法为父查询)

 通过子查询实现

SELECT *
FROM `student`
WHERE `bornDate`>(
		SELECT `bornDate` FROM `student` WHERE `studentName`='黄小平'
		)

执行命令得

mysql 按年 group by mysql按年份分组_子查询_23

练习1

需求说明
1.查询2016年2月17日考试前5名的学员的学号和分数
2.将所有女学生按年龄从大到小排序,从第2条记录开始显示6名女学生的姓名、年龄、出生日期、手机号信息
3.按出生年份分组统计学生人数,将各组中人数达到2人的年份和人数显示出来
4.查询参加2016年2月17日考试的所有学员的最高分、最低分、平均分
1.

SELECT `studentNo`,`studentResult`
FROM `result`
WHERE `examDate`='2016-02-17 00:00:00'


2.

SELECT `studentName` AS '姓名',`bornDate` AS '年龄',`phone` AS '手机'
FROM `student`
ORDER BY `bornDate`
LIMIT 1,6

3.

SELECT YEAR(bornDate)AS 年份, COUNT(studentNo) AS 人数
FROM student
GROUP BY 年份
HAVING 人数>2



4.

SELECT MAX(`studentResult`),MIN(`studentResult`),AVG(`studentResult`)
FROM `result`
WHERE `examDate`='2016-02-17 00:00:00'

练习2

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

#查询参加最近一次Logic Java考试成绩的学生的最高分和最低分
SELECT MAX(studentResult),MIN(studentResult)
FROM result
WHERE examDate=(SELECT MAX(examDate)
		FROM result
		WHERE `subjectNO`=(SELECT subjectNo FROM `subject` WHERE subjectName='Logic Java'))
AND `subjectNO`=(SELECT subjectNo FROM `subject` WHERE subjectName='Logic Java')

执行命令得

mysql 按年 group by mysql按年份分组_Java_24

IN子查询

常用IN替换等于(=)的子查询

IN后面的子查询可以返回多条记录 (IN 相当于 or的操作)

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

#查询“Logic Java”课程考试成绩为60分的学生名单
SELECT *
FROM student
WHERE studentNo IN (SELECT studentNo
		     FROM result
		     WHERE studentResult=60
		     AND subjectNo=(SELECT subjectNo FROM `subject` WHERE subjectName='Logic Java')

)

执行命令得

mysql 按年 group by mysql按年份分组_Java_25

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

实现步骤:

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

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

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

4.获得“Logic Java”课程的在读年级编号

SELECT *
FROM student
WHERE gradeID=(SELECT gradeID FROM `subject` WHERE subjectName='Logic Java' )#Logic Java的在读年级编号
AND studentNo  IN (
	SELECT studentNo
	FROM result
	WHERE subjectNo=(#最近一次Logic Java考试的学生编号
	SELECT subjectNo FROM `subject` WHERE subjectName='Logic Java')#Logic Java的课程编号
	AND   examDate=(SELECT MAX(examDate)
			FROM result
			WHERE `subjectNO`=(SELECT subjectNo FROM `subject` WHERE subjectName='Logic Java'))#最近一次考试时间
	  )

执行命令得

mysql 按年 group by mysql按年份分组_字段_26

NOT IN 子查询

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

SELECT *
FROM student
WHERE gradeID=(SELECT gradeID FROM `subject` WHERE subjectName='Logic Java' )#Logic Java的在读年级编号
AND studentNo NOT IN (
	SELECT studentNo
	FROM result
	WHERE subjectNo=(#最近一次Logic Java考试的学生编号
	SELECT subjectNo FROM `subject` WHERE subjectName='Logic Java')#Logic Java的课程编号
	AND   examDate=(SELECT MAX(examDate)
			FROM result
			WHERE `subjectNO`=(SELECT subjectNo FROM `subject` WHERE subjectName='Logic Java'))#最近一次考试时间
	  )


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

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

SELECT `subjectName` FROM `subject` WHERE `gradeId` IN (
       SELECT `gradeId` FROM `grade` WHERE `gradeName`='S1'
)