首页 > 数据库 >MySQL详解

MySQL详解

时间:2022-10-12 15:57:49浏览次数:85  
标签:name no -- 查询 详解 student MySQL SELECT

MySQL

1.初识mysql

  • JavaEE:企业级Java开发 Web
  • 前端(页面:展示:数据)
  • 后台 (连接点:连接数据库JDBC,连接前端(控制视图跳转,给前端传递数据))
  • 数据库(存数据,Txt,Excel,Word)
    • 只会写代码,学好数据库,基本混饭吃!
    • 操作系统,数据结构与算法!当一个不错的程序猿!
    • 离散数学,数字电路,体系结构,编译原理。+实战经验,优秀程序猿

1.1 为什么学数据库

  • 岗位需求
  • 现在的世界,大数据时代,得数据者得天下
  • 被迫需求:存数据
  • 数据库是所有软件体系中最核心的存在 DBA

1.2 什么是数据库

  • 数据库:(DB,DataBase)
    • 概念:数据仓库,软件,安装在操作系统之(windows,Linux。mac)上的!SQL,可以存储大量的数据,500万!
    • 作用:存储数据,管理数据 Excel

1.3 数据库分类

  • 关系型数据库:(SQL)
    • MySQL, Oracle, sql Server, DB2, SQLite
    • 通过表和表之间,行和列之间的关系进行数据的存储,学员信息表,考勤表,······
  • 非关系型数据库:(NoSQL) Not Only
    • Redis, MongDB
    • 非关系型数据库,对象存储,通过对象自身的属性来决定。
  • DBMS(数据库管理系统)
    • 数据库的管理软件,科学有效的管理我们的数据,维护和获取数据;
    • MySQL ,数据管理系统!

1.4 MySQL简介

  • MySQL是一个关系型数据库管理系统。
  • 发展史:
    • 前世: 瑞典MySQL AB 公司
    • 今身: 属于 Oracle 旗下产品
  • MySQL是最好的 RDBMS (Relational Database Management System,关系数据库管理系统) 应用软件之一。
    • 开源的数据库软件

    • 体积小,速度快,总体拥有成本低,招人成本比较低,所有人必须会~。

    • 中小型网站,或者大型网站,集群

    • 官网: https://www.mysql.com/

1.5 MySQL基本的命令行操作

mysql -uroot -p123456 -- 连接数据库

update mysql.user set authentication_string=password('123456') where user='root' and host='localhost'; -- 修改用户密码

flush privileges; -- 刷新权限
----------------------------
-- 所有的语句都使用;结尾

show databases; -- 查看所有的数据库

mysql> use school; -- 切换数据库  use 数据库名
Database changed

mysql> show tables; -- 显示数据库中所有表的信息

mysql> describe student; -- 显示表的详细信息

create database zyy;  -- 创建一个数据库(这里过于简洁,后面详细介绍)

exit -- 退出连接

-- 单行注释
/**
多行注释
*/



2.操作数据库

2.1 MySQL结构化查询语句分类

名称 解释 命令
DDL (数据定义语言) 定义和管理数据对象,如数据库,数据表等 CREATE、DROP、ALTER
DML (数据操作语言) 用于操作数据库对象中所包含的数据 INSERT、UPDATE、DELETE
DQL (数据查询语言) 用于查询数据库数据 SELECT
DCL (数据控制语言) 用于管理数据库的语言,包括管理权限及数据更改 GRANT、commit、 rollback

2.2 操作数据库语句

  • 操作数据库 》 操作数据库中表 》操作数据库中表的数据
  • mysql关键字不区分大小写
  • 1.创建数据库
CREATE DATABASE [IF NOT EXISTS] student;-- create database [if not exists] 数据库名;
  • 2.删除数据库
DROP DATABASE [IF EXISTS] westos;-- drop database [if exists] 数据库名;
  • 3.使用数据库
-- tab 键上面,如果你的表名或者字段名是一个特殊字符,就需要带``
USE `school`--use 数据库名;
  • 4.查看数据库
SHOW DATABASES; -- 查看所有的数据库

2.3 列的数据类型讲解

数值
  • tinyint 十分小的数据 1个字节
  • smallint 较小的数据 2个字节
  • mediumint 中等大小的数据 3个字节
  • int 标准的整数 4个字节

  • bigint 较大的数据 8个字节

  • float 浮点数 4个字节

  • double 浮点数 8个字节

  • decimal 字符串形式的浮点数 (金融计算的时候,一般是使用decimal)

字符串
  • char 字符串固定大小的 0~255
  • varchar 可变字符串 0~65535 (常量的变量 String)
  • tinytext 微型文本 2^8 -1
  • text 文件串 2^16 -1 (保存大文本)
时间日期 java.util.Date
  • date YYYY-MM-DD 日期格式

  • time HH:mm:ss 时间格式

  • datetime YYYY-MM-DD HH:mm:ss 最常用的时间格式

  • timestamp 时间戳,1970.1.1到现在的毫秒数!较为常用!

  • year 年份表示

null
  • 没有值,未知
  • 注意:不要使用NULL进行运算,结果为NULL

2.4 数据库的字段属性

  • Unsigned:

    • 无符号的整数
    • 声明了该列不能声明为负数
  • Zerofill:

    • 0填充的
    • 不足的位数,使用0来填充 int(3), 5 — 005
  • 自增:

    • 通用理解为自增,自动在上一条记录的基础上+1(默认)
    • 通常用来设计唯一的主键,index,必须是整数类型
    • 可以自定义设计主键自增的起始值和步长
  • 非空 null/not null:

    • not null,如果不给他赋值,就会报错
    • null,如果不给他赋值,默认就是null
  • 默认:

    • 设置默认的值
    • 如果不赋值,就会存默认值
  • 拓展:

/*
每个表,都必须存在以下五个字段  未来做项目用的,表示一个记录存在的意义

id          主键
version     乐观锁
is_delete   伪删除
gmt_create  创建时间
gmt_update  修改时间

*/

2.5 创建数据库表

-- 目标:创建一个school数据库
-- 创建student学生表,使用sql创建
-- 学号 姓名 性别 出生日期 家庭地址  email

-- 注意点:使用英文()  表的名称和字段尽量使用``括起来
-- AUTO_INCREMENT 自增
-- COMMENT 属性注释
-- DEFAULT 默认值
-- 字符串使用单引号括起来
-- 所有的语句后面加上英文逗号,最后一个不加
-- PRIMARY KEY主键,一个表一般只有一个唯一的主键
CREATE TABLE IF NOT EXISTS `student` (
  `id` INT(4) NOT NULL AUTO_INCREMENT COMMENT '学号',
  `name` VARCHAR(30) NOT NULL DEFAULT '匿名' COMMENT '姓名',
  `sex` VARCHAR(2) NOT NULL DEFAULT '女' COMMENT '性别',
  `birthday` DATETIME NOT NULL COMMENT '出生日期',
  `address` VARCHAR(100) DEFAULT NULL COMMENT '家庭地址',
  `email` VARCHAR(30) DEFAULT NULL COMMENT '邮箱',
  PRIMARY KEY(`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8

-- 查看建立数据库的语句
SHOW CREATE DATABASE SCHOOL
DESC STUDENT --显示表的结构
  • 格式
CREATE TABLE [IF NOT EXISTS] `表名` (
    `字段名` 列类型[属性]  [索引]  [注释],
    `字段名` 列类型[属性]  [索引]  [注释],
    `字段名` 列类型[属性]  [索引]  [注释],
    ...
)[表类型][字符集设置][注释]

  • 常用命令:
SHOW CREATE DATABASE `school` ; -- 查看创建数据库的语句
SHOW CREATE TABLE `student`; -- 查看student数据表的定义语句
DESC `student`; -- 查看表的结构

2.6 MyIASM和InnoDB区别


                      MYISAM             INNODB     
事务支持 不支持 支持
数据行锁定 不支持 支持
外键约束 不支持 支持
全文索引 支持 不支持
表空间的大小 较小 较大,约为MYISAM的2倍
  • 常规使用操作:

    • MYISAM 节约空间,速度较快
    • INNODB 安全性高,事务的处理,多表多用户操作
  • 在物理空间存在的位置

    • 所有的数据库文件都存在data目录下,一个文件夹就对应一个数据库
    • 本质还是文件的存储!
  • mysql引擎在物理文件上的区别

    • INNODB 在数据库表中只有一个*.frm文件,以及上级目录下的ibdata1文件
    • MYISAM 对应的文件
      • *.frm 表结构的定义文件
      • *.MYD 数据文件(data)
      • *.MYI 索引文件 (index)
  • 设置数据库表的字符集编码

    • CHARSET=utf8
    • 不设置的话,会是mysql默认的字符集编码(不支持中文),mysql的默认编码是Latin1,不支持中文
    • 在my.ini中配置默认的编码
       character-set-server=utf8

2.7 修改和删除数据表字段

  • 修改
-- 修改表名.  ALTER TABLE 旧表名 RENAME AS 新表名
ALTER TABLE teacher RENAME AS teacher1
-- 增加表的字段.  ALTER TABLE 表名 ADD 字段名 列属性
ALTER TABLE teacher1 ADD age INT(11)

-- 修改表的字段 (重命名,修改约束!)
-- ALTER TABLE 表名 MODIFY 字段名 列属性[]
ALTER TABLE teacher1 MODIFY age VARCHAR(11) -- 修改约束
-- ALTER TABLE 表名 CHANGE 字段名 新名字 列属性[]
ALTER TABLE teacher1 CHANGE age  age1 INT(1)-- 字段重命名

-- 删除表的字段:ALTER TABLE 表名 DROP 字段名
ALTER TABLE teacher1 DROP age1


  • 删除
-- 删除表(如果存在再删除)
DROP TABLE IF EXISTS teacher1
  • 所有的创建和删除操作尽量加上判断,以免报错.

  • 注意点:

    • `` 字段名,使用这个包裹!
    • 注释:单行注释 # 注释内容  多行注释 /* 注释内容 */  单行注释 -- 注释内容
    • sql 关键字大小写不敏感,建议写小写。
    • 所有的符号全部用英文

3.MySQL数据管理

3.1 外键(了解即可)

  • 方式一:在创建表的时候,增加约束(麻烦,比较复杂)
CREATE TABLE `grade`(
`gradeid` INT(10) NOT NULL AUTO_INCREMENT COMMENT '年级id',
`gradename` VARCHAR(50) NOT NULL COMMENT '年级名称',
PRIMARY KEY (`gradeid`)
)ENGINE=INNODB DEFAULT CHARSET=utf8

-- 学生表的 gradeid 字段 要去引用年级表的gradeid
-- 定义外键KEY
-- 给这个外键添加约束(执行引用) references 引用
CREATE TABLE IF NOT EXISTS `student3`(
		`id` INT(4) NOT NULL AUTO_INCREMENT COMMENT'学号',
		`name` VARCHAR(30) NOT NULL DEFAULT'匿名' COMMENT'姓名',
		`pwd` VARCHAR(20) NOT NULL DEFAULT'123456' COMMENT'密码',
		`birthday` DATETIME DEFAULT NULL COMMENT'出生日期',
		`gradeid` INT(10) NOT NULL COMMENT '学生年级',
		`address` VARCHAR(100) DEFAULT NULL COMMENT'家庭住址',
		`email` VARCHAR(50) DEFAULT NULL COMMENT'邮箱',
		PRIMARY KEY(`id`),
		KEY `FK_gardeid` (`gradeid`),
    CONSTRAINT `FK_gardeid` FOREIGN KEY (`gradeid`) REFERENCES `grade` (gradeid)
)ENGINE=INNODB DEFAULT CHARSET=utf8

  • 注意:删除有外键关系的表的时候,必须先删除引用的表(从表),再删除被引用的表(主表)

  • 方式二: 创建表成功后,添加外键的约束。

CREATE TABLE `grade`(
`gradeid` INT(10) NOT NULL AUTO_INCREMENT COMMENT '年级id',
`gradename` VARCHAR(50) NOT NULL COMMENT '年级名称',
PRIMARY KEY (`gradeid`)
)ENGINE=INNODB DEFAULT CHARSET=utf8

CREATE TABLE IF NOT EXISTS `student3`(
		`id` INT(4) NOT NULL AUTO_INCREMENT COMMENT'学号',
		`name` VARCHAR(30) NOT NULL DEFAULT'匿名' COMMENT'姓名',
		`pwd` VARCHAR(20) NOT NULL DEFAULT'123456' COMMENT'密码',
		`birthday` DATETIME DEFAULT NULL COMMENT'出生日期',
		`gradeid` INT(10) NOT NULL COMMENT '学生年级',
		`address` VARCHAR(100) DEFAULT NULL COMMENT'家庭住址',
		`email` VARCHAR(50) DEFAULT NULL COMMENT'邮箱',
		PRIMARY KEY(`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8


-- 创建表的时候没有外键关系。
ALTER TABLE `student3`
ADD CONSTRAINT `FK_gradeid` FOREIGN KEY(`gradeid`) REFERENCES `grade`(`gradeid`);
-- ALTER TABLE `表` ADD CONSTRAINT 约束名 FOREIGN KEY(作为外键的列)引用到哪个表的哪个字段.

  • 以上的操作都是物理外键,数据库级别外键,我们不建议使用!(避免数据库过多造成困扰)
  • 最佳实践
    • 数据库就是单纯的表,只用来存数据,只有行(数据)和列(字段)。
    • 我们想使用多张表的数据,想使用外键(程序去实现)。

3.2 DML语言(全部记住)

  • 数据库意义:数据存储,数据管理.
  • DML语言:数据操作语言.
    • Insert (添加数据语句)
    • update (更新数据语句)
    • delete (删除数据语句)

3.3 添加

  • Insert
-- 插入语句(添加)
-- insert into 表名([字段名1,字段2,字段3]) values ('值1','值2','值3',······)
INSERT INTO `grade`(`gradename`) VALUES('大四')

-- 由于主键自增我们可以省略(如果不写表的字段,他就会一一匹配)

-- 一般写插入语句,我们一定要数据和字段一一对应!

-- 插入多个字段
INSERT INTO `grade`(`gradename`) VALUES('大二'),('大一')

INSERT INTO `student3`(`name`) VALUES ('张三')

INSERT INTO `student3`(`name`,`pwd`) VALUES ('张三','aaaaaa')

INSERT INTO `student3`(`name`,`pwd`) 
VALUES('李四','lalalala'),('王五','wuwuwuwu')

INSERT INTO `student3` 
VALUES (5,'王二麻子','7777777','1999-12-23',1,'新疆','email')

  • 语法: insert into 表名([字段名1,字段2,字段3]) values ('值1','值2','值3',······)

  • 注意事项:

    • 1.字段和字段之间用英文逗号隔开。
    • 2.字段可以省略,但是后面的值必须要一一对应,不能少。
    • 3.可以同时插入多条数据,VALUES后面的值,需要使用逗号隔开即可。VALUES(),()......

3.4 修改

  • update  修改谁  (条件) set 原来的值=新值
-- 语法:
-- UPDATE 表名 SET colnum_name = value where [条件]

-- 修改学员名字,带了条件。
UPDATE `student3` SET `name`='狂神' WHERE id=1;
UPDATE `student3` SET `name`='狂神' WHERE id>=1;
UPDATE `student3` SET `name`='狂神11' WHERE id<>1;
UPDATE `student3` SET `name`='狂神22' WHERE id!=1;
UPDATE `student3` SET `name`='狂神33' WHERE id BETWEEN 2 AND 5;

-- 不指定条件的情况下,会改动所有表!
UPDATE `student3` SET `name`='长江7号'

-- 修改多个属性,逗号隔开。
UPDATE `student3` SET `name`='狂神',`email`='21312312qq.com' WHERE id = 1;

-- 通过多个条件定位数据,无上限!
UPDATE `student3` SET `name`='狂神' WHERE `name`='长江7号' AND pwd='123456'
UPDATE `student3` SET `birthday`=CURRENT_TIME WHERE `name`='长江7号' AND pwd='123456'

  • 条件: where 子句 运算符 id 等于某个值,大于某个值,在某个区间内修改…
  • 语法: UPDATE 表名 SET colnum_name = value,[colnum_name = value,......] where [条件]

  • 操作符会返回布尔值
      操作符          含义           范围            结果     
= 等于 5 = 6 false
<> 或 != 不等于 5 <> 6 true
> 大于 5 > 6 false
< 小于 5 < 6 true
>= 大于等于 6,7 >= 6 true
<= 小于等于 5,6 <= 6 true
BETWEEN…AND… 在某个范围内 [2 , 5] 3 true
AND 我和你 && 5 > 1 and 1 > 2 true
OR 我或你 5 > 1 or 1 > 2 true
  • 注意事项:

    • 1.column_name 是数据库的列,带上``.
    • 2.条件,是筛选的条件,如果没有指定,则会修改所有的列.
    • 3.value 是一个具体的值,也可以是一个变量.
    • 4.多个设置的属性之间,使用英文逗号隔开.

3.5 删除

  • delete 命令
  • 语法: delete from 表名 [where 条件]
-- 删除数据(避免这样写,会全部删除)
DELETE FROM `student3`

-- 删除指定数据
DELETE FROM `student3` WHERE id=1
  • TRUNCATE 命令
    • 作用:完全清空一个数据库表,表的结构和索引约束不会变.
-- 清空student3表
TRUNCATE TABLE `student3`

  • delete 和 TRUNCATE 区别
    • 相同点: 都能删除数据,都不会删除表结构.
    • 不同:
      • TRUNCATE 重新设置自增列 计数器会归零.
      • TRUNCATE 不会影响事务.
-- 测试 delete 和 TRUNCATE 的区别
CREATE TABLE `test`(
`id` INT(4) NOT NULL AUTO_INCREMENT,
`coll` VARCHAR(20) NOT NULL ,
PRIMARY KEY(`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8

INSERT INTO `test`(`coll`) VALUES('1'),('2'),('3')

DELETE FROM `test` -- 不会影响自增

TRUNCATE TABLE `test` -- 自增会归零

  • delete删除的问题 重启数据库,现象.
    • innoDB 自增列会从1开始(存在内存当中,断电即失)
    • MyISAM 继续从上一个自增量开始(存在文件中,不会丢失)


4.DQL查询数据

  • (Data Query Language) :数据查询语言
  • 所有的查询操作都用它 Select
  • 简单的查询,复杂的查询它都能做
  • 数据库中最核心的语言,最重要的语句
  • 使用频率最高的语句

SELECT 语法
  • 注意 : [ ] 括号代表可选的 , { }括号代表必选得
SELECT [ALL | DISTINCT] -- DISTINCT 去重
{* | table.* | [table.field1[as alias1][,table.field2[as alias2]][,...]]}
FROM table_name [as table_alias]
  [left | right | inner join table_name2]  -- 联合查询
  [WHERE ...]  -- 指定结果需满足的条件
  [GROUP BY ...]  -- 指定结果按照哪几个字段来分组
  [HAVING]  -- 过滤分组的记录必须满足的次要条件
  [ORDER BY ...]  -- 指定查询记录按一个或多个条件排序
  [LIMIT {[offset,]row_count | row_countOFFSET offset}];
   -- 指定查询的记录从哪条至哪条


  • 测试数据SQL
-- 创建一个school数据库
create  database  `school`;
-- 创建一张年级表
use `school`;
drop table if exists `grade`;
 create  table  `grade`(
     `GradeID` int(4) not null auto_increment  comment '年级编号',
       `GradeName` varchar(50) not  null comment '年级名称',
      primary  key (`GradeID`)
 )ENGINE=INNODB AUTO_INCREMENT=6  DEFAULT CHARSET=utf8;

-- 添加数据插入年级数据
insert  into `grade` (`GradeID`, `GradeName`) values(1,'大一'),(2,'大二'),(3,'大三'),(4,'大四'),(5,'预科班');

-- 创建reult 成绩表
drop table if exists `result`;
create table  `result`(
`StudentNo` int(4) not null  comment '学号',
 `SubjectNo` int(4) not  null comment  '课程编号',
    `ExamDate`  DATETIME not null comment '考试日期',
    `StudentResult` int(4) not  null  comment '考试成绩',
    key  `SubjectNo`(`SubjectNo`)
)ENGINE=INNODB DEFAULT CHARSET=utf8;

-- 插入成绩数据  这里仅插入了一组,其余自行添加
insert into `result`(`studentno`,`subjectno`,`examdate`,`studentresult`)
values(1000,1,'2013-11-11 16:00:00',85),
(1000,2,'2013-11-12 16:00:00',70),
(1000,3,'2013-11-11 09:00:00',68),
(1000,4,'2013-11-13 16:00:00',98),
(1000,5,'2013-11-14 16:00:00',58);

-- 创建 student学生表
drop table if exists `student`;
create  table  `student`(
   `StudentNo` int(4) not null  comment '学号',
    `LoginPwd` varchar(20) not null,
    `StudentName` varchar(20) DEFAULT  NULL comment '学生姓名',
    `Sex` TINYINT(1) DEFAULT NULL  comment  '性别,取值0或1',
    `GradeID` int(4) DEFAULT NULL comment '年级编号',
    `Phone` varchar(50) not null comment '联系电话  允许为空',
    `Address` varchar(255) not null  comment '地址  允许为空',
    `BornDate`  DATETIME DEFAULT null comment '出生时间',
    `Email` varchar(50) not  null comment '邮箱账号   允许为空',
    `IdentityCard` varchar(18)  DEFAULT  null  comment '身份证',
    primary key(`StudentNo`),
    UNIQUE key `IdentityCard` (`IdentityCard`),
    key `Email` (`Email`)
)ENGINE=INNODB DEFAULT CHARSET=utf8;

-- 添加数据插入学生数据 
insert  into  `student` (`StudentNo`,`LoginPwd`,`StudentName`,`Sex`, `GradeID`,`Phone` ,`Address`,`BornDate`, `Email`, `IdentityCard`) values(1001,'123456','李四',1,3,'18786506942','山海','1999-12-11 00:00:00','[email protected]','522428199912110812'),(1002,'123456','李林',0,3,'18786506942','西安','1999-02-11 00:00:00','[email protected]','522428199912110832'),(1003,'123456','韩立',1,3,'1878655542','北京','1999-02-11 00:00:00','[email protected]','412428199912110812');

-- subject  表
-- 创建科目表
drop table if exists `subject`;
create  table `subject`(
  `SubjectNO`  int(4) not null auto_increment comment '课程标号',
    `SubjectName` varchar(50) DEFAULT NULL comment '课程名称',
    `ClassHour` int(4) DEFAULT NULL comment '学时',
    `GradeID`  int(4)  DEFAULT null comment  '年级编号',
    primary key (`SubjectNO`)
)ENGINE=INNODB DEFAULT CHARSET=utf8;

-- 添加数据 
insert into `subject`(`subjectno`,`subjectname`,`classhour`,`gradeid`)values
(1,'高等数学-1',110,1),
(2,'高等数学-2',110,2),
(3,'高等数学-3',100,3),
(4,'高等数学-4',130,4),
(5,'C语言-1',110,1),
(6,'C语言-2',110,2),
(7,'C语言-3',100,3),
(8,'C语言-4',130,4),
(9,'Java程序设计-1',110,1),
(10,'Java程序设计-2',110,2),
(11,'Java程序设计-3',100,3),
(12,'Java程序设计-4',130,4),
(13,'数据库结构-1',110,1),
(14,'数据库结构-2',110,2),
(15,'数据库结构-3',100,3),
(16,'数据库结构-4',130,4),
(17,'C#基础',130,1);


4.1 指定查询字段

  • 查询指定字段
-- 查询全部的学生   SELECT 字段 FROM 表名;
  SELECT * FROM student;
  
-- 查询指定字段
  SELECT student_name, student_no FROM student;
  • AS 别名
-- 别名,给结果起一个名字 AS  可以给字段起别名,也可以给表起别名
  
  SELECT student_name AS '学号', student_no AS '姓名' FROM student;
  
-- 函数 concat(a,b)
  SELECT CONCAT('姓名:', student_no)  AS '新姓名' FROM student;

  • 语法 : SELECT 字段,... FROM 表名
  • 有的时候,列名字不是那么的见名知义。所以我们会对其起别名 AS 字段名 as 新名字

  • 去重 distinct: 作用:去除Select 查询出来的结果中重复的数据 只显示一条
-- 查询一下有哪些同学参加了考试,成绩
SELECT * FROM result -- 查询全部的考试成绩
-- 查询有哪些同学参加了考试
SELECT `studentNo` FROM result 
-- 发现重复数据,去重
SELECT DISTINCT `studentNo` FROM result 

  • 数据库的列(表达式)
SELECT VERSION()  -- 查询系统版本 (函数)
SELECT 100*3-1 AS 计算结果 -- 用来计算 (表达式)
SELECT @@auto_increment_increment  -- 查询自增的步长 (变量)

-- 学生年级 +1 查看
SELECT `name`,`gradeid` +1 AS '升学后' FROM student

  • 数据库中的表达式:文本值,列,null,函数,计算表达式,系统变量
  • 语法: select 表达式 from 表名

4.2 where 条件子句

  • 作用:检索数据中符合条件的值
  • 搜索的条件由一个或者多个表达式组成,结果布尔值
逻辑运算符
       运算符               语法             描述     
and    && a and b    a&&b 逻辑与两个都为真,结果为真
or  \(\mid\)\(\mid\) a or b  a\(\mid\)\(\mid\)b 逻辑或,其中一个为真则结果为真
not  ! not a   !a 逻辑非,真为假,假为真
  • 尽量使用英文字母
-- ====================  where  ====================

-- 查询考试成绩在 95 ~ 100分之间

SELECT student_no,student_result FROM result;

-- and
SELECT student_no,student_result FROM result
WHERE student_result>95 AND student_result<=100;
-- && 
SELECT student_no,student_result FROM result
WHERE student_result>95 && student_result<=100;


-- 模糊查询(区间)
SELECT student_no,student_result FROM result
WHERE student_result BETWEEN 95 AND 100;

-- 除了1000号学生之外的学生的成绩
-- !=
SELECT student_no,student_result FROM result
WHERE student_no != 1000;
-- not
SELECT student_no,student_result FROM result
WHERE NOT student_no = 1000;


  • 模糊查询操作符详解
模糊查询:比较运算符
       运算符               语法             描述     
IS NULL a is null 如果操作符为null,结果为真
IS NOT NULL a is not null 如果操作符不为null,结果为真
BWTWEEN…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,…其中的某一个,则结果为真
-- ====================  模糊查询  ======================
  
 -- 查询姓刘的同学

-- like 结合 
--   %(代表0到任意个字符)
--   _(代表1)

-- 查询姓刘的同学
SELECT `student_no`,`student_name` FROM `student`
WHERE student_name LIKE '刘%';

-- 查询姓刘的同学,名字后面只有一个字的
SELECT `student_no`,`student_name` FROM `student`
WHERE student_name LIKE '刘_';

-- 查询姓刘的同学,名字后面有两个字的
SELECT `student_no`,`student_name` FROM `student`
WHERE student_name LIKE '刘__';

-- 查询名字中间有嘉字的同学
SELECT `student_no`,`student_name` FROM `student`
WHERE student_name LIKE '%%嘉%';

===================IN(具体的一个或者多个值)===========================
-- in (具体的一个或者多个值)
-- 查询学号1001,1002,1003号学号
SELECT `student_no`,`student_name` FROM `student`
WHERE student_no IN ('1001','1002','1003');

SELECT `StudentNo`,`StudentName` FROM `student`
WHERE StudentNo = 1001
SELECT `StudentNo`,`StudentName` FROM `student`
WHERE StudentNo = 1002
SELECT `StudentNo`,`StudentName` FROM `student`
WHERE StudentNo = 1003

-- 查询在北京的学生
SELECT `student_no`,`student_name` FROM `student`
WHERE address IN ('北京');

===================NULL NOT NULL===================================
-- null
-- 查询地址为空的学生
SELECT `student_no`,`student_name` FROM `student`
WHERE address = '' OR address IS NULL;

-- not null
-- 查询有出生日期的同学 不为空
SELECT `student_no`,`student_name` FROM `student`
WHERE born_date IS NOT NULL;

-- 查询没有出生日期的同学 为空
SELECT `student_no`,`student_name` FROM `student`
WHERE born_date IS NULL;

4.3 联表查询

  • JOIN对比与 七种jion理论

ffd


fff

  • 联表查询 join
-- =====================联表查询 join ==============================

-- 查询参加了考试的同学(学号,姓名,科目编号,分数)
SELECT * FROM student;
SELECT * FROM result;


/*
1. 分析需求,分析查询的字段来自哪些表
2.确定使用哪种连接查询?7种
确定交叉点(这两个表中哪个数据是相同的)
判断的条件: 学生表中 studentNo = 成绩表中 studentNo 

*/
-- join on 连接查询
-- where 等值查询


-- inner join
SELECT st.`student_no`,st.`student_name`,re.`subject_no`,re.`student_result` 
FROM student AS st
INNER JOIN result AS re ON 
st.`student_no`=re.`student_no`;

-- right join
SELECT st.`student_no`,st.`student_name`,re.`subject_no`,re.`student_result` 
FROM student st
RIGHT JOIN result re ON 
st.`student_no`=re.`student_no`;

-- left join
SELECT st.`student_no`,st.`student_name`,re.`subject_no`,re.`student_result` 
FROM student st
LEFT JOIN result re ON 
st.`student_no`=re.`student_no`;

-- 查询缺考的同学
SELECT st.`student_no`,st.`student_name`,re.`subject_no`,re.`student_result` 
FROM student st
LEFT JOIN result re ON 
st.`student_no`=re.`student_no`
WHERE re.`student_result` IS NULL;

-- 查询了参加考试的同学信息(学号,学生姓名,科目名称,分数)
SELECT stu.`student_no`,stu.`student_name`,sub.`subject_name`,res.`student_result`
FROM `student` stu
RIGHT JOIN `result` res 
ON res.`student_no`=stu.`student_no`
INNER JOIN `subject` sub
ON res.`subject_no`=sub.`subject_no`;

-- 查询学员所属的年级(学号,学生的姓名,年级名称)
SELECT `student_no`,`student_name`,`grade_name`
FROM student stu
INNER JOIN `grade` gra
ON stu.`grade_id`=gra.`grade_id`;

-- 查询了参加数据结构-1考试的同学信息(学号,学生姓名,科目名称,分数)
SELECT stu.`student_no`,stu.`student_name`,sub.`subject_name`,res.`student_result`
FROM student stu
INNER JOIN `result` res
ON stu.`student_no` = res.`student_no`
INNER JOIN `subject` sub
ON res.`subject_no`=sub.`subject_no`
WHERE sub.`subject_name`='数据结构-1';


-- 我要查询哪些数据 select ...
-- 从哪几个表中查 from 表 XXX join 连接的表 on 交叉条件
-- 假设存在一种多张表查询,慢慢来,先查询两张表然后再慢慢增加

--FROM a LEFT JOIN b   左为准
--FROM a RIGHT JOIN b	右为准

       操作               描述     
inner join 如果表中至少有一个匹配,就返回行
left join 会从左边中返回所有的值,即使右表中没有匹配
right join 会从右边中返回所有的值,即使左表中没有匹配

  • 自连接及联表查询
  • 自连接: 自己的表和自己的表连接,核心:一张表拆为两张一样的表即可
父类
       pid               category_id             category_name     
1 2 信息技术
1 3 软件开发
1 5 美术设计

       pid               category_id             category_name     
3 4 数据库
2 8 办公信息
3 6 web开发
5 7 ps技术

  • 操作:查询父类对应的子类关系
       父类               子类     
信息技术 办公信息
软件开发 数据库
软件开发 web开发
美术设计 ps技术
  • 创建自连接需要的表
-- 创建表
-- unsigned 无符号
-- auto_increment=9 自增的起始值
DROP TABLE IF EXISTS `category` ;
CREATE TABLE `category` (
  `category_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主题id',
  `pid` INT(10) NOT NULL COMMENT '父id',
  `category_name` VARCHAR(50) NOT NULL COMMENT '主题名字',
  PRIMARY KEY (`category_id`)
) ENGINE=INNODB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8;

-- 插入值
INSERT INTO `category`(`category_id`,`pid`,`category_name`)
VALUES('2','1','信息技术'),
('3','1','软件开发'),
('4','3','数据库'),
('5','1','美术设计'),
('6','3','web开发'),
('7','5','ps技术'),
('8','2','办公信息');

SELECT * FROM `category`;

  • 自连接
-- 查询父子信息,把一张表看为两个一模一样的表
SELECT a.`category_name` AS '父栏目',b.`category_name` AS '子栏目'
FROM `category` AS a, `category` AS b
WHERE a.`category_id`=b.`pid`;


4.4 分页和排序

  • 排序
-- 排序: 升序 ASC  降序 DESC
-- ORDER BY 通过那个字段排序,怎么排
-- 查询的结果根据成绩降序 排序
SELECT stu.`student_no`,stu.`student_name`,sub.`subject_name`,res.`student_result`
FROM student stu
INNER JOIN `result` res
ON stu.`student_no` = res.`student_no`
INNER JOIN `subject` sub
ON res.`subject_no`=sub.`subject_no`
WHERE sub.`subject_name`='数据结构-1'
ORDER BY `student_result` DESC;


  • 分页
-- 100w
-- 为什么要分页
-- 缓解数据库压力,给人更好的体验   瀑布流
-- 分页,每页只显示五条数据
-- 语法 : limit 起始值,页面的大小
-- 网页应用:当前,总的页数,每页大小
-- LIMIT 0,5    1~5
-- LIMIT 1,5    2~6
-- LIMIT 6,5
SELECT stu.`student_no`,stu.`student_name`,sub.`subject_name`,res.`student_result`
FROM student stu
INNER JOIN `result` res
ON stu.`student_no` = res.`student_no`
INNER JOIN `subject` sub
ON res.`subject_no`=sub.`subject_no`
WHERE sub.`subject_name`='数据结构-1'
ORDER BY `student_result` DESC
LIMIT 1,5;
-- 第一页 limit 0,5    (1-1)*5
-- 第二页 limit 5,5    (2-1)*5
-- 第三页 limit 10,5   (3-1)*5
-- 第N页 limit 10,5    (n-1)*pageSize,pageSize
-- pageSize,页面大小
-- (n-1)*pageSize,起始值
-- n,当前页
-- 总页数 = (数据总数%页面大小==0)? (数据总数/页面大小) : (数据总数/页面大小 + 1)

-- 思考:
-- 查询科目高等数学-2,课程成绩排名前十的学生,并且分数要大于60的学生信息(学号,姓名,课程名称,分数)
SELECT stu.`student_no`,stu.`student_name`,sub.`subject_name`,res.`student_result`
FROM student stu
INNER JOIN `subject` sub
ON stu.`grade_id`=sub.`grade_id`
INNER JOIN `result` res
ON sub.`subject_no`=res.`subject_no`
WHERE sub.`subject_name`='高等数学-2'
AND res.`student_result`>60
ORDER BY res.`student_result`
LIMIT 0,10;

  • 语法: limit (查询起始下标,页面大小)

4.5 子查询和嵌套查询

  • where (这个值是计算出来的)
  • 本质: 在where语句中嵌套一个子查询语句
/*============== 子查询和嵌套查询 ================
什么是子查询?
   在查询语句中的WHERE条件子句中,又嵌套了另一个查询语句
   嵌套查询可由多个子查询组成,求解的方式是由里及外;
   子查询返回的结果一般都是集合,故而建议使用IN关键字;
*/

-- 查询 数据库结构-1 的所有考试结果(学号,科目编号,成绩),并且成绩降序排列
-- 方法一:使用连接查询
SELECT studentno,r.subjectno,StudentResult
FROM result r
INNER JOIN `subject` sub
ON r.`SubjectNo`=sub.`SubjectNo`
WHERE subjectname = '数据库结构-1'
ORDER BY studentresult DESC;

-- 方法二:使用子查询(执行顺序:由里及外)
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

-- 方法二:使用连接查询+子查询
-- 分数不小于80分的学生的学号和姓名
SELECT r.studentno,studentname FROM student s
INNER JOIN result r ON s.`StudentNo`=r.`StudentNo`
WHERE StudentResult>=80

-- 在上面SQL基础上,添加需求:课程为 高等数学-2
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'
  )
)


4.5 分组和过滤

  • 分组和过滤
 -- 查询不同课程的平均分,最高分,最低分
 -- 前提:根据不同的课程进行分组
 
 SELECT subjectname,AVG(studentresult) AS 平均分,MAX(StudentResult) AS 最高分,MIN(StudentResult) AS 最低分
 FROM result AS r
 INNER JOIN `subject` AS s
 ON r.subjectno = s.subjectno
 GROUP BY r.subjectno
 HAVING 平均分>80;
 
 /*
 where写在group by前面.
 要是放在分组后面的筛选
 要使用HAVING..
 因为having是从前面筛选的字段再筛选,而where是从数据表中的>字段直接进行的筛选的
 */


  • HAVING:再筛选

4.6 select 小结

  • SELECT语法
SELECT [ALL | DISTINCT]
{* | table.* | [table.field1[as alias1][,table.field2[as alias2]][,...]]}
FROM table_name [as table_alias]
  [left | right | inner join table_name2]  -- 联合查询
  [WHERE ...]  -- 指定结果需满足的条件
  [GROUP BY ...]  -- 指定结果按照哪几个字段来分组
  [HAVING]  -- 过滤分组的记录必须满足的次要条件
  [ORDER BY ...]  -- 指定查询记录按一个或多个条件排序
  [LIMIT {[offset,]row_count | row_countOFFSET offset}];
   -- 指定查询的记录从哪条至哪条

select小结中文解释
顺序很重要:

select 去重 要查询的字段 from 表 (注意:表和字段可以取别名)
XXX join 要连接的表 on 等值判断
where (具体的值,子查询语句)
Group by (通过哪个字段来分组)
Having (过滤分组后的信息,条件和where是一样的,位置不同)
Order by (通过哪个字段排序)[升序/降序]
Limit startindex,pagesize

业务层面:
查询:跨表,跨数据库

5.MySQL 常用函数

5.1 常用函数

-- ============================== 常用函数=====================================
-- 数学运算

SELECT ABS(-8); -- 绝对值
SELECT CEILING(9.4); -- 向上取整
SELECT FLOOR(9.4);  -- 向下取整
SELECT RAND(); -- 返回0-1随机数
SELECT SIGN(-10); -- 判断一个数的符号 0-0 负数返回-1 正数返回1



-- 字符串函数
SELECT CHAR_LENGTH('2323232'); -- 返回字符串长度
SELECT CONCAT('我','233'); -- 拼接字符串
SELECT INSERT('java',1,2,'cccc'); -- 从某个位置开始替换某个长度
SELECT UPPER('abc'); -- 小写
SELECT LOWER('ABC');-- 大写
SELECT REPLACE('坚持就能成功','坚持','努力'); -- 替换出现的指定字符串
SELECT INSTR('kuangshen','h'); -- 返回第一次出现的子串的索引
SELECT SUBSTR('狂神说坚持就能!!!成功',4,6); -- 返回指定的子字符串(原字符串,截取的位置,截取的长度)
SELECT REVERSE('狂神说坚持就能成功'); -- 反转


-- 查询姓 周 的同学 ,改成邹
SELECT REPLACE(studentname,'周','邹'); FROM student
WHERE studentname LIKE '周%';

-- 时间跟日期函数(记住)
SELECT CURRENT_DATE() -- 获取当前日期
SELECT CURDATE() -- 获取当前日期
SELECT NOW() -- 获取当前日期
SELECT LOCATIME()  -- 本地时间
SELECT SYSDATE()  -- 系统时间

-- 获取年月日,时分秒
SELECT YEAR(NOW()) -- 年
SELECT MONTH(NOW())-- 月
SELECT DAY(NOW())-- 日
SELECT HOUR(NOW())  -- 时
SELECT MINUTE(NOW()) -- 分
SELECT SECOND(NOW()) -- 秒

-- 系统
SELECT SYSTEM_USER()  -- 获取本机服务器名字
SELECT USER()     /*用户*/
SELECT VERSION() /*版本*/

5.2 聚合函数及分组过滤

       函数名称               描述     
COUNT() 计数
SUM() 求和
AVG() 平均值
MAX() 最大值
MIN() 最小值
-- 聚合函数

-- 都能统计 表中数据(想查询一个表中有多少个记录,就使用这个count())


 /*COUNT:非空的*/
 SELECT COUNT(studentname) FROM student;-- Count(字段),会忽略所有的 null 值
 SELECT COUNT(*) FROM student;-- Count(*),不会忽略 null 值,本质 计算行数
 SELECT COUNT(1) FROM student;  /*推荐*/ -- Count(1),不会忽略所有的 null 值,本质 计算行数
 

 -- 从含义上讲,count(1) 与 count(*) 都表示对全部数据行的查询。
 -- count(字段) 会统计该字段在表中出现的次数,忽略字段为null 的情况。即不统计字段
 为null 的记录。
 -- count(*) 包括了所有的列,相当于行数,在统计结果的时候,包含字段为null 的记录;
 -- count(1) 用1代表代码行,在统计结果的时候,包含字段为null 的记录 。
 /*
 很多人认为count(1)执行的效率会比count(*)高,原因是count(*)会存在全表扫描,
 而count(1)可以针对一个字段进行查询。其实不然,count(1)和count(*)都会对全表进行扫描,
 统计所有记录的条数,包括那些为null的记录,因此,它们的效率可以说是相差无几。而
 count(字段)则与前两者不同,它会统计该字段不为null的记录条数。
 
 下面它们之间的一些对比:
 
 1)在表没有主键时,count(1)比count(*)快
 2)有主键时,主键作为计算条件,count(主键)效率最高;
 3)若表格只有一个字段,则count(*)效率较高。
 */
 
 SELECT SUM(StudentResult) AS 总和 FROM result;
 SELECT AVG(StudentResult) AS 平均分 FROM result;
 SELECT MAX(StudentResult) AS 最高分 FROM result;
 SELECT MIN(StudentResult) AS 最低分 FROM result;

  • 分组查询和过滤
-- 查询不同课程的平均分,最高分,最低分,平均分大于80
--核心:根据不同的课程分组
SELECT sub.subject_name AS '课程',
AVG(res.student_result) AS '平均分',
MAX(res.student_result) AS '最高分',
MIN(res.student_result) AS '最低分'
FROM result res
INNER JOIN `subject` sub
ON res.`subject_no`=sub.`subject_no`
GROUP BY res.`subject_no`--通过什么字段来分组
HAVING AVG(res.student_result) >80;


5.3 数据库级别的MD5加密

  • 什么是MD5:MD5即Message-Digest Algorithm 5(信息-摘要算法5),用于确保信息传输完整一致。是计算机广泛使用的杂凑算法之一(又译摘要算法、哈希算法),主流编程语言普遍已有MD5实现。将数据(如汉字)运算为另一固定长度值,是杂凑算法的基础原理,MD5的前身有MD2、MD3和MD4。
    • 主要增强算法复杂度和不可逆性
    • MD5不可逆,具体的值的md5是一样的
    • MD5破解网站的原理,背后有一个字典,MD5加密后的值,加密前的值

--  ===================测试MD5 加密====================
CREATE TABLE `testmd5`(
`id`  INT(4)  NOT NULL,
`name`  VARCHAR(20)  NOT  NULL,
`pwd`   VARCHAR(50)  not NULL,
PRIMARY KEY(`id`)
)ENGINE=INNODB DEFAULT  CHARSET=utf8;

-- 插入一些数据
--  明文密码
INSERT  INTO testmd5  
VALUES(1,'张三','123456'),
(2,'zhaoda','123456'),
(3,'lisi','123456'),
(4,'wangwu','123456');

-- 加密
UPDATE  testmd5 SET pwd=MD5(pwd) WHERE id=1;

UPDATE  testmd5 SET pwd=MD5(pwd);-- 加密全部密码
-- 插入的时候加密
INSERT  INTO testmd5  VALUES(6,'小明',MD5('123456'));
select * from  testmd5;

-- 如何校验:将用户传递进来的密码  进行md5加密  然后对比加密后的值
SELECT *FROM testmd5  WHERE name='小明' AND pwd=MD5('123456');

6.更多参考

狂神-MySQL最新教程

标签:name,no,--,查询,详解,student,MySQL,SELECT
From: https://www.cnblogs.com/xingchenyang/p/16435820.html

相关文章

  • Linux Epoll 详解
       Epoll作为Linux系统中的核心武器之一,在高吞吐、高并发的IO系统中经常遇见Epoll的身影,列如Redis、Nginx、Skynet等都使用到了IO多路复用技术。我们可以先创建一个e......
  • parted命令详解
    Parted是一个比fdisk更高级的工具,它支持多种分区表格式,包括MS-DOS和GPT。它允许用户创建,删除,调整大小,缩小,移动和复制分区,重新组织磁盘使用,以及将数据复制到新硬盘,但在缩小......
  • MySQL 中NULL和空值的区别
    NULL和空值NULL也就是在字段中存储NULL值,空值也就是字段中存储空字符('')。1、占用空间区别mysql>selectlength(NULL),length(''),length('1');+--------------+------......
  • mysql 插入Timestamp 少8个小时
    转:mysql插入timeStamp类型数据时间相差8小时的解决办法 mysql插入时间少八个小时 MySQL插入时间差八小时问题的解决方法如果时间和你本地当前时间一致说明mysql的时......
  • Mysql中的MVCC
     Mysql到底是怎么实现MVCC的?这个问题无数人都在问,但google中并无答案,本文尝试从Mysql源码中寻找答案。 在Mysql中MVCC是在Innodb存储引擎中得到支持的,Innodb为每行记录都......
  • Mysql主主同步配置方法
    环境服务器a:172.16.0.123服务器b:172.16.0.132Mysql版本:5.6.22SystemOS:CentOSrelease6.3创建同步用户服务器a和b分别建立一个同步用户:mysql>grantreplications......
  • MySQL存储IP地址的方法
    IP转数字函数inet_aton()mysql>selectinet_aton('192.168.1.1');+--------------------------+|inet_aton('192.168.1.1')|+--------------------------+|3232......
  • MySQL的语句执行顺序
    MySQL的语句一共分为11步,如下图所标注的那样,最先执行的总是FROM操作,最后执行的是LIMIT操作。其中每一个操作都会产生一张虚拟的表,这个虚拟的表作为一个处理的输入,只是这些虚......
  • 关于mysql archive存储引擎
    政府还有一个让数据库专家摊上更多事情的职能,就是安全控制和数据审计。那些管理着海量数据仓库的企业官员常常得回答诸如“何人何时修改了什么”或者“何人何时查看了什么”......
  • mysql给表的字段加索引
    1、添加普通索引ALTERTABLE`table_name`ADDINDEXindex_name(`column`)2、添加主键索引ALTERTABLE`table_name`ADDPRIMARYKEY(`column`)3、添加唯一索引(UNIQ......