MySQL 数据库
1、数据库简介2、SQL语言3、DQL数据查询
1、掌握SQL语言2、掌握DDL和DML的使用3、掌握DML的单表查询
第一章 数据库简介
可以保存数据的地方:硬盘和内存
硬盘:文件中,也可以保存到数据库中【底层也是文件】
学生信息,保存在文件 IO
场景:增删改查等。
能不能做成系统:对文件进行增删改查,以及安全加密,多用户等操作
数据库:就是对文件各种操作的封装,做成了一个系统。
内存:容器中【数组,集合】,redis数据库
1.1 简介
数据库(DataBase,DB):指长期保存在计算机的存储设备上,按照一定规则组织起来,可以被各种用户或应用共享的数据集合。
数据库管理系统(DataBase Management System,DBMS):指一种操作和管理数据库的大型软件,用于建立、使用和维护数据库,对数据库进行统一管理和控制,以保证数据库的安全性和完整性。用户通过数据库管理系统访问数据库中的数据。
数据库软件应该为数据库管理系统,数据库是通过数据库管理系统创建和操作的。
数据库:存储、维护和管理数据的集合。
1.2 常见数据库管理系统
- Oracle:Oracle数据库被认为是业界目前比较成功的关系型数据库管理系统。Oracle数据库可以运行在UNIX、Windows等主流操作系统平台,完全支持所有的工业标准,并获得最高级别的ISO标准安全性认证。
- MySQL:MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS (Relational Database Management System,关系数据库管理系统) 应用软件。
- DB2:DB2是IBM公司的产品,DB2数据库系统采用多进程多线索体系结构,其功能足以满足大中公司的需要,并可灵活地服务于中小型电子商务解决方案。
Microsoft SQL Server:SQL Server 是Microsoft 公司推出的关系型数据库管理系统。具有使用方便可伸缩性好与相关软件集成程度高等优点。
1.3 MySQL5.5安装和卸载
安装和配置步骤:



















验证是否安装成功,打开cmd输入,如上图所示。
然后输入密码,正确进入表示安装成功。c:\>mysql -u root -p
卸载MySQL
1.停止服务,使用c:\>net stop mysql命令停止服务,c:\>net start mysql命令启动服务。
2.在控制面板—>”程序和功能”中,找到“mysql程序”,点击卸载。
3.删除安装目录,一般默认在C:\Program Files\MySQL。
4.删除数据库文件存放目录,一般默认在C:\ProgramData\MySQL。1.4 MySQL5.7.x 版本安装
同意协议

开发模式

请注意安装需要的依赖环境,如果想安装的功能缺少对应环境是无法安装的,需先安装环境后才可以安装

下一步的时候会提示缺少环境,此处的提示是说你期望安装的产品中缺少依赖,不一定提示的是数据库服务器安装的依赖,可能是其他功能组件的依赖缺少

此处发现没有 mysql server, 说明它对应的依赖缺少,可以先执行安装这些可以安装的,之后安装完依赖后再重新安装其他模块,我们此处的操作是先安装依赖,然后后退再次安装

下载安装前面提示的 mysql server 需要的 vc2013后,vc2013 如果在64位系统上面建议32和64的程序都安装,然后在上图的地方后退,重新 next 就可以看到可以安装 mysql server 了


进行第一步配置,除了需要设置密码外,后面的步骤基本上都是下一步下一步


设置 root 密码




finish 后回到当前页面继续配置

此处先 check, 后下一步

执行完此步骤 下一步 finish 配置完成
第二章 SQL语言
2.1 概述
SQL:Structure Query Language(结构化查询语言),SQL被美国国家标准局(ANSI)确定为关系型数据库语言的美国标准,后来被国际化标准组织(ISO)采纳为关系数据库语言的国际标准。<br /> 各数据库厂商都支持ISO的SQL标准,**普通话**<br /> 各数据库厂商在标准的基础上做了自己的扩展,**方言**<br /> SQL 是一种标准化的语言,它允许你在数据库上执行操作,如创建项目,查询内容,更新内容,并删除条目等操作。<br /> Create, Read, Update, and Delete 通常称为CRUD操作。
2.2 SQL语句分类
- DDL(Data Definition Language):数据定义语言,用来定义数据库对象:库、表、列等。
- DML(Data Manipulation Language):数据操作语言,用来定义数据库记录(数据)。
- DCL(Data Control Language):数据控制语言,用来定义访问权限和安全级别。
DQL(Data Query Language):数据查询语言,用来查询记录(数据)。
注意sql语句以;结尾<br />DQL > DML > DDL > DCL<br />如果新建一个数据库,新建表 : DDL<br />如果对数据库中的student 表进行新增,修改,删除 : DML<br />查询Student数据 : DQL<br />修改数据库的事务,密码,用户权限: DCL
2.3 DDL操作数据库
- 创建:CREATE DATABASE语句用于创建新的数据库:
SQL> CREATE DATABASE mydb1;SQL> CREATE DATABASE mydb2 character SET GBK;SQL> CREATE DATABASE mydb3 character SET utf8 COLLATE utf8_general_ci;
COLLATE 指的是排序规则,或者校对集,对于mysql中的那些字符类型的列,如Varchar,Char,Text类型的列,都需要指定COLLATE类型来告诉MySQL如何对该列进行排序和比较。SQL语句一般都是大写的,如果你是小写的,会自动变换为大写再执行。MYSQL中的COLLATE是什么?https://www.jianshu.com/p/f8707b8461d3
- 查看
查看当前数据库服务器中的所有数据库
SQL> SHOW DATABASES;
查看前面创建的mydb2数据库的定义信息
SQL> Show CREATE DATABASE mydb2;
- 修改
查看服务器中的数据库,并把mydb2的字符集修改为utf8;
SQL> ALTER DATABASE mydb2 character SET utf8;ps:修改完数据库字符集,需要重启mysql数据库。注意,这个修改只能对新表有用,修改之前已经存在的无用
删除
SQL> DROP DATABASE mydb3;
其他语句
查看当前使用的数据库
SQL> Select database();
切换数据库
SQL> USE mydb2;
2.4 DDL操作表
CREATE TABLE语句用于创建新表。
语法:
CREATE TABLE 表名(
字段1 字段类型(长度) 约束,
字段2 字段类型(长度) 约束,
…
字段n 字段类型(长度) 约束
);
示例:
SQL> CREATE TABLE Employees(id INT NOT NULL,age INT NOT NULL,first VARCHAR(255),last VARCHAR(255),PRIMARY KEY ( id ));
常用数据类型:
int:整型
double:浮点型,例如double(5,2)表示最多5位,其中必须有2位小数,即最大值为999.99;
char:固定长度字符串类型; char(10) ‘aaa ‘ 占10位
varchar:可变长度字符串类型; varchar(10) ‘aaa’ 占3位
text:字符串类型;
blob:字节类型;
date:日期类型,格式为:yyyy-MM-dd;
time:时间类型,格式为:hh:mm:ss
timestamp:时间戳类型 yyyy-MM-dd hh:mm:ss 会自动赋值 CURRENT_TIMESTAMP
datetime:日期时间类型 yyyy-MM-dd hh:mm:ss
主键约束:primary key唯一约束:unique [key]非空约束:not null默认约束:default外键约束:foreign key自动增长:auto_increment
SQL> DROP TABLE table_name;
SHOW TABLES;
DESC employee;
ALTER TABLE employee ADD image blob;
ALTER TABLE employee MODIFY job varchar(60);
ALTER TABLE employee DROP image;
RENAME TABLE employee TO user;
SHOW CREATE TABLE user;
ALTER TABLE user CHARACTER SET gbk;
ALTER TABLE user CHANGE name username varchar(100);
2.5 DML操作
DML是对表中的数据进行增、删、改的操作。不要与DDL混淆了。
主要包括:INSERT 、UPDATE、 DELETE
小知识:
在mysql中,字符串类型和日期类型都要用单引号括起来。
空值:null
(1)插入操作:INSERT:
语法: INSERT INTO 表名(列名1,列名2 …)VALUES(列值1,列值2…);
注意:列名与列值的类型、个数、顺序要一一对应。
可以把列名当做java中的形参,把列值当做实参。
参不要超出列定义的长度。
如果插入空值,请使用null
插入的日期和字符一样,都使用引号括起来。
create table emp(id int primary key,name varchar(100) not null,gender varchar(10) not null,birthday date,salary float(10,2),entry_date date,resume text);INSERT INTO emp(id,name,gender,birthday,salary,entry_date,resume)VALUES(1,'zhangsan','female','1990-5-10',10000,'2015-5-5','goodgirl');INSERT INTO emp(id,name,gender,birthday,salary,entry_date,resume)VALUES(2,'lisi','male','1995-5-10',10000,'2015-5-5','good boy');INSERT INTO emp(id,name,gender,birthday,salary,entry_date,resume)VALUES(3,'你好','male','1995-5-10',10000,'2015-5-5','good boy');
小知识:
Show variables like ‘character%’;
Set character_set_client=gbk;Set character_set_results=gbk;或者SET NAMES ‘gbk’;
(2)修改操作:INSERT:
语法:UPDATE 表名 SET 列名1=列值1,列名2=列值2 … WHERE 列名=值
练习:
UPDATE emp SET salary=5000
UPDATE emp SET salary=3000 WHERE name=’ zhangsan’;
UPDATE emp SETsalary=4000,gender='female' WHERE name='lisi';
UPDATE emp SETsalary=salary+1000 WHERE name='wu';
(3)删除操作:DELETE:
语法 : DELETE 表名 【WHERE 列名=值】
练习 :
DELETE FROM emp WHERE name=‘zs’;
DELETE FROM emp;
TRUNCATE TABLE emp;
- DELETE 删除表中的数据,表结构还在;删除后的数据可以找回
- TRUNCATE 删除是把表直接DROP掉,然后再创建一个同样的新表。
- 删除的数据不能找回。执行速度比DELETE快。
第三章 DQL数据查询
数据库执行DQL语句不会对数据进行改变,而是让数据库发送结果集给客户端。
查询返回的结果集是一张虚拟表。
查询关键字:SELECT
语法: SELECT 列名 FROM表名 【WHERE —> BROUP BY—>HAVING—> ORDER BY】
SELECT selectionlist /要查询的列名称/
FROM table_list /要查询的表名称/
WHERE condition /行条件/
GROUP BY grouping_columns /对结果分组/
HAVING condition /分组后的行条件/
ORDER BY sorting_columns /对结果分组/
LIMIT offset_start, row_count /结果限定_/
示例操作:#创建表stuCREATE TABLE stu (sid CHAR(6),sname VARCHAR(50),age INT,gender VARCHAR(50));#添加数据INSERT INTO stu VALUES('S_1001', 'liuYi', 35, 'male');INSERT INTO stu VALUES('S_1002', 'chenEr', 15, 'female');INSERT INTO stu VALUES('S_1003', 'zhangSan', 95, 'male');INSERT INTO stu VALUES('S_1004', 'liSi', 65, 'female');INSERT INTO stu VALUES('S_1005', 'wangWu', 55, 'male');INSERT INTO stu VALUES('S_1006', 'zhaoLiu', 75, 'female');INSERT INTO stu VALUES('S_1007', 'sunQi', 25, 'male');INSERT INTO stu VALUES('S_1008', 'zhouBa', 45, 'female');INSERT INTO stu VALUES('S_1009', 'wuJiu', 85, 'male');INSERT INTO stu VALUES('S_1010', 'zhengShi', 5, 'female');INSERT INTO stu VALUES('S_1011', 'xxx', NULL, NULL);
#创建雇员表CREATE TABLE emp(empno INT,ename VARCHAR(50),job VARCHAR(50),mgr INT,hiredate DATE,sal DECIMAL(7,2),comm decimal(7,2),deptno INT) ;#添加数据INSERT INTO emp values(7369,'SMITH','CLERK',7902,'1980-12-17',800,NULL,20);INSERT INTO emp values(7499,'ALLEN','SALESMAN',7698,'1981-02-20',1600,300,30);INSERT INTO emp values(7521,'WARD','SALESMAN',7698,'1981-02-22',1250,500,30);INSERT INTO emp values(7566,'JONES','MANAGER',7839,'1981-04-02',2975,NULL,20);INSERT INTO emp values(7654,'MARTIN','SALESMAN',7698,'1981-09-28',1250,1400,30);INSERT INTO emp values(7698,'BLAKE','MANAGER',7839,'1981-05-01',2850,NULL,30);INSERT INTO emp values(7782,'CLARK','MANAGER',7839,'1981-06-09',2450,NULL,10);INSERT INTO emp values(7788,'SCOTT','ANALYST',7566,'1987-04-19',3000,NULL,20);INSERT INTO emp values(7839,'KING','PRESIDENT',NULL,'1981-11-17',5000,NULL,10);INSERT INTO emp values(7844,'TURNER','SALESMAN',7698,'1981-09-08',1500,0,30);INSERT INTO emp values(7876,'ADAMS','CLERK',7788,'1987-05-23',1100,NULL,20);INSERT INTO emp values(7900,'JAMES','CLERK',7698,'1981-12-03',950,NULL,30);INSERT INTO emp values(7902,'FORD','ANALYST',7566,'1981-12-03',3000,NULL,20);INSERT INTO emp values(7934,'MILLER','CLERK',7782,'1982-01-23',1300,NULL,10);
#创建部门表CREATE TABLE dept(deptno INT,dname varchar(14),loc varchar(13));#添加数据INSERT INTO dept values(10, 'ACCOUNTING', 'NEW YORK');INSERT INTO dept values(20, 'RESEARCH', 'DALLAS');INSERT INTO dept values(30, 'SALES', 'CHICAGO');INSERT INTO dept values(40, 'OPERATIONS', 'BOSTON');
3.1 简单查询
SELECT * FROM stu;
SELECT sid, sname, age FROM stu;
3.2 条件查询
条件查询就是在查询时给出WHERE子句,在WHERE子句中可以使用如下运算符及关键字:
l =、!=、<>、<、<=、>、>=;
l BETWEEN…AND;
l IN(set);
l IS NULL;
l AND;
l OR;
l NOT;
SELECT * FROM stu WHERE gender='female' AND age<50;
SELECT * FROM stu WHERE sid ='S_1001' ORsname='liSi';
SELECT * FROM stuWHERE sid IN ('S_1001','S_1002','S_1003');
SELECT * FROM tab_studentWHERE sid NOT IN('S1001','S1002','S_1003');
SELECT * FROM stu WHERE age IS NULL;
SELECT *FROM stuWHERE age>=20 AND age<=40;或者SELECT *FROM stuWHERE age BETWEEN 20 AND 40;
SELECT *FROM stuWHERE gender!='male';或者SELECT *FROM stuWHERE gender<>'male';或者SELECT *FROM stuWHERE NOT gender='male';
SELECT *FROM stuWHERE NOT sname IS NULL;或者SELECT *FROM stuWHERE sname IS NOT NULL;
3.3 模糊查询
当想查询姓名中包含a字母的学生时就需要使用模糊查询了。模糊查询需要使用关键字LIKE。
通配符:
_ 任意一个字母
%:任意0~n个字母
‘张%’
SELECT *FROM stuWHERE sname LIKE '_';
模糊查询必须使用LIKE关键字。其中 “”匹配任意一个字母,5个“”表示5个任意字母。
(2)查询姓名由5个字母构成,并且第5个字母为“i”的学生记录
SELECT *FROM stuWHERE sname LIKE 'i';
(3)查询姓名以“z”开头的学生记录
SELECT *FROM stuWHERE sname LIKE 'z%';
其中“%”匹配0~n个任何字母。
(4)查询姓名中第2个字母为“i”的学生记录
SELECT *FROM stuWHERE sname LIKE '_i%';
(5)查询姓名中包含“a”字母的学生记录
SELECT *FROM stuWHERE sname LIKE '%a%';
3.4 字段控制查询
(1)去除重复记录
去除重复记录(两行或两行以上记录中系列的上的数据都相同),例如emp表中sal字段就存在相同的记录。当只查询emp表的sal字段时,那么会出现重复记录,那么想去除重复记录,需要使用DISTINCT:
SELECT DISTINCT sal FROM emp;
(2)查看雇员的月薪与佣金之和
因为sal和comm两列的类型都是数值类型,所以可以做加运算。如果sal或comm中有一个字段不是数值类型,那么会出错。
SELECT *,sal+comm FROM emp;
comm列有很多记录的值为NULL,因为任何东西与NULL相加结果还是NULL,所以结算结果可能会出现NULL。下面使用了把NULL转换成数值0的函数IFNULL:
SELECT *,sal+IFNULL(comm,0) FROMemp;
(3)给列名添加别名
在上面查询中出现列名为sal+IFNULL(comm,0),这很不美观,现在我们给这一列给出一个别名,为total:
SELECT *, sal+IFNULL(comm,0) AStotal FROM emp;
给列起别名时,是可以省略AS关键字的:
SELECT *,sal+IFNULL(comm,0) total FROM emp;
3.5 排序
(1) 查询所有学生记录,按年龄升序排序
SELECT *FROM stuORDER BY sage ASC;或者SELECT *FROM stuORDER BY sage;
(2) 查询所有学生记录,按年龄降序排序
SELECT *FROM stuORDER BY age DESC;
(3) 查询所有雇员,按月薪降序排序,如果月薪相同时,按编号升序排序
SELECT * FROM empORDER BY sal DESC,empno ASC;
3.6 聚合函数
聚合函数是用来做纵向运算的函数:
l COUNT():统计指定列不为NULL的记录行数;
l MAX():计算指定列的最大值,如果指定列是字符串类型,那么使用字符串排序运算;
l MIN():计算指定列的最小值,如果指定列是字符串类型,那么使用字符串排序运算;
l SUM():计算指定列的数值和,如果指定列类型不是数值类型,那么计算结果为0;
l AVG():计算指定列的平均值,如果指定列类型不是数值类型,那么计算结果为0;
IFNULL()
(1) COUNT
当需要纵向统计时可以使用COUNT()。
l 查询emp表中记录数:
SELECT COUNT(*) AS cnt FROM emp;
l 查询emp表中有佣金的人数:
SELECT COUNT(comm) cnt FROM emp;
注意,因为count()函数中给出的是comm列,那么只统计comm列非NULL的行数。
l 查询emp表中月薪大于2500的人数:
SELECT COUNT(*) FROM emp
WHERE sal > 2500;
l 统计月薪与佣金之和大于2500元的人数:
SELECT COUNT(*) AS cnt FROM empWHERE sal+IFNULL(comm,0) > 2500;
l 查询有佣金的人数,以及有领导的人数:
SELECT COUNT(comm), COUNT(mgr)FROM emp;
(2) SUM和AVG
当需要纵向求和时使用sum()函数。
l 查询所有雇员月薪和:
SELECT SUM(sal) FROM emp;
l 查询所有雇员月薪和,以及所有雇员佣金和:
SELECT SUM(sal), SUM(comm) FROMemp;
l 查询所有雇员月薪+佣金和:
SELECT SUM(sal+IFNULL(comm,0))FROM emp;
l 统计所有员工平均工资:
SELECT AVG(sal) FROM emp;
(3) MAX和MIN
l 查询最高工资和最低工资:
SELECT MAX(sal), MIN(sal) FROM emp;
求工资最高的人和钱,工资对低的人和钱:
select ename,sal from emp
where sal = (select max(sal) from emp)
or sal = (select min(sal) from emp);
select ename,sal from emp where sal =(select min(sal) from emp)
union select ename,sal from emp where sal =(select max(sal) from emp);
3.7 分组查询
当需要分组查询时需要使用GROUP BY子句,例如查询每个部门的工资和,这说明要使用部分来分组。
注:凡和聚合函数同时出现的列名,则一定要写在group by 之后
3.7.1 分组查询
l 查询每个部门的部门编号和每个部门的工资和:
SELECT deptno, SUM(sal)
FROM emp
GROUP BY deptno;
l 查询每个部门的部门编号以及每个部门的人数:
SELECT deptno,COUNT(*)
FROM emp
GROUP BY deptno;
l 查询每个部门的部门编号以及每个部门工资大于1500的人数:
SELECT deptno,COUNT(*)
FROM emp
WHERE sal>1500
GROUP BY deptno;
3.7.2 HAVING子句
l 查询工资总和大于9000的部门编号以及工资和:
SELECT deptno, SUM(sal)
FROM emp
GROUP BY deptno
HAVING SUM(sal) > 9000;
注:having与where的区别:
1.having是在分组后对数据进行过滤,where是在分组前对数据进行过滤
2.having后面可以使用分组函数(统计函数)<br /> where后面不可以使用分组函数。<br /> WHERE是对分组前记录的条件,如果某行记录没有满足WHERE子句的条件,那么这行记录不会参加分组;而HAVING是对分组后数据的约束。
3.8 LIMIT
LIMIT用来限定查询结果的起始行,以及总行数。
1查询5行记录,起始行从0开始
SELECT * FROM emp LIMIT 0, 5;
注意,起始行从0开始,即第一行开始!
2查询10行记录,起始行从3开始
SELECT* FROM emp LIMIT 3, 10;
3.8.3 分页查询
如果一页记录为10条,希望查看第3页记录应该怎么查呢?
l 第一页记录起始行为0,一共查询10行;
l 第二页记录起始行为10,一共查询10行;
l 第三页记录起始行为20,一共查询10行;
查询语句书写顺序:select – from- where- groupby- having- order by-limit
查询语句执行顺序:from - where -group by -having - select - order by-limit
总结
小米 100万 5万
limit 0,20 分页查询
limit 20,20
limit 40,20
作业题
1.设有成绩表如下所示
1.查询两门及两门以上不及格的学生姓名
2.查询学生平均分
3.查询姓名是张三的学生 成绩和
4.将学生信息按照 分数倒序
5.获取学生信息中 分数最低的学生姓名和分数最高的学生姓名
6.查询两门及两门以上不及格同学的平均分。
编号 姓名 科目 分数
1 张三 数学 90
2 张三 语文 50
3 张三 地理 40
4 李四 语文 55
5 李四 政治 45
6 王五 政治 30
7 李四 数学 80
8 王五 语文 70
2.写出 SQL语句的格式 : 插入 ,更新 ,删除
表名 user
name tel content date
张三 13333663366 大专毕业 2006-10-11
张三 13612312331 本科毕业 2006-10-15
张四 021-55665566 中专毕业 2006-10-15
(a).有一新记录(小王 13254748547 高中毕业 2007-05-06)请用SQL语句新增至表中
(b).请用sql语句把张三的时间更新成为当前系统时间
(c).请写出删除名为张四的全部记录
3.写出 SQL语句的格式 :对emp表进行查询操作
1.找出奖金高于工资的雇员
2.找出奖金高于工资60%的雇员
3.找出部门10中所有经理和部门20中所有店员的信息
4.找出部门10中所有经理(MANAGER),部门20中所有店员,既不是经理又不是店员但其薪资大于或等于2000的所有员工的信息。
5.查询没有奖金或者奖金低于100的员工信息
6.查询姓名不带”R”的员工姓名
7.显示员工的姓名和入职时间,根据入职时间,将最老的员工排放在最前面。
8.显示所有员工的姓名、工作和工资,按照工作的降序排序,若工作相同则按工资升序排序。
面试题
有3 个表(15 分钟):【基础】
Student 学生表(学号,姓名,性别,年龄,组织部门)
Course 课程表(编号,课程名称)
Sc 选课表(学号,课程编号,成绩)
表结构如下:
1)写一个SQL 语句,查询选修了’计算机原理’的学生学号和姓名(3 分钟)
2)写一个SQL 语句,查询’周星驰’同学选修了的课程名字(3 分钟)
3)写一个SQL 语句,查询选修了5 门课程的学生学号和姓名(9 分钟)
登录Mysql服务器:
mysql -uroot -proot
可以通过↑或者↓翻看我们之前执行过的SQL命令。
DDL:【对数据库或者表或者列进行增删改查】
一、操作数据库
1、新建数据库
create database mydb01;
create database mydb02 character set gbk;
create database mydb03 character set gbk collate gbk_chinese_ci;
2、查询所有数据库
show databases;
3、查看之前创建的数据库【了解】
show create database mydb03;
4、修改数据库
alter database mydb02 character set utf8;
5、删除数据库
drop database mydb03;
6、查看当前正在使用哪个数据库。
select database(); // null
7、切换数据库
use mydb01;
注意事项:
create database mydb01; 创建数据库如果没有指定字符集,默认是安装时指定的字符集。
二、操作表
1、新建表 一定要先指定数据库
create table stu2(id int(3) not null);
create table employee(
id int(5) not null,
name varchar(10),
salary double(5,2),
primary key (id)
);
什么是主键?
一个数据库表,必须给定主键【不给也不报错,会警告】,主键就是能够区分该条记录是唯一的一个或者多个字段。
表中的每一条记录都是唯一的,这个唯一性靠主键区分。
1,“张三”,1000
2, “张三”,1000
2、查看表
show tables;
3、查看表结构 查看各个字段详情
desc stu;
4、删除表
drop table stu2;
5、新增字段
alter table employee add image blob;
6、修改字段
alter table employee modify salary double(7,2);
7、删除列
alter table employee drop image;
8、对表名进行重命名
rename table stu to student;
DML语句:主要是通过SQL语句对数据库中的数据进行增删改。
1、新增数据
insert into employee(id,name,salary) values(1,’张三’,2000);
insert into employee(id,name) values(4,’Mantis’);
insert into employee values(3,’神龙大侠’);
2、查询数据【不是dml语句】
select * from employee;
3、修改数据 null 无法参与运算
update employee set name = ‘阿宝’ where id=2;
update employee set salary = salary + 1000;
4、删除表中的数据
delete from employee where salary is null;
delete from employee; 删除表中所有数据,但是一般清空表中的数据不用该语句,慢
truncate table 表名 删除表中所有数据,快
delete from employee,一行行删除,表结构还在,数据还有可能找回。
truncate table 表名; 直接删除表,然后重新创建一个一模一样的表,数据无法找回
DQL 语句: 查询表中的数据【重要】
语法:
SELECT 列名 FROM表名 【WHERE —> BROUP BY—>HAVING—> ORDER BY】
1、查询一个表中的所有数据
select from 表名;
select from employee where salary >= 3000;
select name,id from employee;
SQL优化:
1、SQL语句关键字大写
2、查询语句不要,要指定你想要的列名。
3、where条件的前后顺序:select from stu where ename=’zhangsan’ and sex=’nan’;
先把能够过滤掉大部分数据的条件放在前面,后面就可以根据前面的结果集继续过滤。
课程回顾
1、数据库简介
2、SQL语言
3、DQL数据查询
1、掌握SQL语言数据的完整性
2、掌握内连接
3、掌握外连接
4、掌握子查询
5、熟练多表查询操作
6、了解SQL优化
第四章 数据的完整性
作用:保证用户输入的数据保存到数据库中是正确的。
确保数据的完整性 = 在创建表时给表中添加约束
完整性的分类:
- 实体完整性:
- 域完整性:
- 引用完整性:
4.1 实体完整性
实体:即表中的一行(一条记录)代表一个实体(entity)
实体完整性的作用:标识每一行数据不重复。
约束类型:
主键约束(primary key)
唯一约束(unique)
自动增长列(auto_increment)4.1.1 主键约束(primary key)
注:每个表中要有一个主键。
特点:数据唯一,且不能为null
示例:
第一种添加方式:
第二种添加方式:此种方式优势在于,可以创建联合主键CREATE TABLE student( id int primary key, name varchar(50) );CREATE TABLE student( id int, name varchar(50), primary key(id) );
第三种添加方式:CREATE TABLE student( classid int, stuid int, name varchar(50), primary key(classid,stuid) );CREATE TABLE student( id int, name varchar(50) ); ALTER TABLE student ADD PRIMARY KEY (id);4.1.2 唯一约束(unique)
特点:数据不能重复。CREATE TABLE student( Id int primary key, Name varchar(50) unique );4.1.3 自动增长列(auto_increment)
sqlserver数据库 (identity) oracle数据库( sequence)
给主键添加自动增长的数值,列只能是整数类型 ```sql CREATE TABLE student( Id int primary key auto_increment, Name varchar(50) ); INSERT INTO student(name) values(‘tom’);
insert into d values(‘wangwu’); insert into d values(null,’wangwu’); 自增列也是列,d后面如果没有写列名,默认所有列都需要插入,自增列可以使用null占个位 只有整数数值类型才会有这个自增,其他字符类型没有。
<a name="RGhBG"></a>
##### 4.2 域完整性
域完整性的作用:限制此单元格的数据正确,不对照此列的其它单元格比较<br />域代表当前单元格<br />域完整性约束:数据类型 非空约束(not null) 默认值约束(default)<br />check约束(mysql不支持)check(sex='男'or sex='女')
<a name="EkYmz"></a>
###### 4.2.1 数据类型:(数值类型、日期类型、字符串类型)
<a name="IWP66"></a>
###### 4.2.2 非空约束:not null
```sql
CREATE TABLE student(
Id int pirmary key,
Name varchar(50) not null,
Sex varchar(10)
);
INSERT INTO student values(1,’tom’,null);
4.2.3 默认值约束 default
CREATE TABLE student(
Id int pirmary key,
Name varchar(50) not null,
Sex varchar(10) default '男'
);
insert intostudent1 values(1,'tom','女');
insert intostudent1 values(2,'jerry',default);
insert into e(name) values('zz');
insert into e values();
4.3 引用完整性(参照完整性)[了解,在企业开发中一般通过逻辑去关联表]
外键约束:FOREIGN KEY
示例:
CREATE TABLE student(
sid int pirmary key,
name varchar(50) not null,
sex varchar(10) default '男'
);
create table score(
id int,
score int,
sid int ,
CONSTRAINT fk_score_sid foreign key(sid) references student(sid)
);
-- 外键列的数据类型一定要与主键的类型一致
第二种添加外键方式。
ALTER TABLE score1 ADD CONSTRAINT fk_stu_score FOREIGN KEY(sid) REFERENCES stu(id);
数据库:开发人员来讲:保存数据
not null
if(phoneNum == null){
phoneNum = '';
或者给用户输出 手机号码不允许为空
不要等数据库报错
}
外键
所有业务都要进行判断,不要让数据库干这个事儿
第五章 多表查询
多个表之间是有关系的,那么关系靠谁来维护?
多表约束:外键约束。
5.1 多表的关系
5.1.1 一对多关系
客户和订单,分类和商品,部门和员工.
一对多建表原则:在多的一方创建一个字段,字段作为外键指向一的一方的主键.
学生表 成绩表
1 多
5.1.2 多对多关系
学生和课程:
多对多关系建表原则:需要创建第三张表,中间表中至少两个字段,这两个字段分别作为外键指向各自一方的主键.
5.1.3 一对一关系【客户表100 20 80】
在实际的开发中应用不多.因为一对一可以创建成一张表.
两种建表原则:
唯一外键对应:假设一对一是一个一对多的关系,在多的一方创建一个外键指向一的一方的主键,将外键设置为unique.
主键对应:让一对一的双方的主键进行建立关系.
学生表 学生拓展表
图书管理系统
book 书的类别 借阅信息 student
timestamp : 可以自动更新时间【当前时间】
insert into jie_detail(book_id,stu_id,type,create_time) values(3,8,’jie’,null);
5.2 多表查询
多表查询有如下几种:
1 合并结果集;UNION 、 UNION ALL
2 连接查询
2.1内连接 [INNER] JOIN ON
2.2外连接 OUTER JOIN ON
- 左外连接 LEFT [OUTER] JOIN
- 右外连接 RIGHT [OUTER] JOIN
- 全外连接(MySQL不支持)FULL JOIN
5.2.1 合并结果集
作用:合并结果集就是把两个select语句的查询结果合并到一起!
合并结果集有两种方式:
l UNION:去除重复记录,例如:SELECT FROM t1 UNION SELECT FROM t2;
l UNION ALL:不去除重复记录,例如:SELECT FROM t1 UNION ALL SELECT FROM t2。

注意:被合并的两个结果:列数、列类型必须相同。
select ename,phone from student union select name,phone_num from user;
5.2.2 连接查询
连接查询就是求出多个表的乘积,例如t1连接t2,那么查询出的结果就是t1*t2。
连接查询会产生笛卡尔积,假设集合A={a,b},集合B={0,1,2},则两个集合的笛卡尔积为{(a,0),(a,1),(a,2),(b,0),(b,1),(b,2)}。可以扩展到多个集合的情况。
那么多表查询产生这样的结果并不是我们想要的,那么怎么去除重复的,不想要的记录呢,当然是通过条件过滤。通常要查询的多个表之间都存在关联关系,那么就通过关联关系去除笛卡尔积。
示例 1:现有两张表
CREATE TABLE emp(
empno INT,
ename VARCHAR(50),
job VARCHAR(50),
mgr INT,
hiredate DATE,
sal DECIMAL(7,2),
comm decimal(7,2),
deptno INT
);
#添加数据SQL语句省略
CREATE TABLE dept(
deptno INT,
dname varchar(14),
loc varchar(13)
);
#添加数据SQL语句省略
执行如下SQL语句
select * from emp,dept;

使用主外键关系做为条件来去除无用信息
SELECT * FROM emp,dept WHERE emp.deptno=dept.deptno;

上面查询结果会把两张表的所有列都查询出来,也许你不需要那么多列,这时就可以指定要查询的列了。
SELECT emp.ename,emp.sal,emp.comm,dept.dname
FROM emp,dept
WHERE emp.deptno=dept.deptno;

一:内连接
上面的连接语句就是内连接,但它不是SQL标准中的查询方式,可以理解为方言!
SQL标准的内连接为:
SELECT *
FROM emp e
INNER JOIN dept d
ON e.deptno=d.deptno;
内连接的特点:查询结果必须满足条件。
二:外连接
包括左外连接和右外连接,外连接的特点:查询出的结果存在不满足条件的可能。
a.左外连接
SELECT * FROM emp e
LEFT OUTER JOIN dept d
ON e.deptno=d.deptno;
左连接是先查询出左表(即以左表为主),然后查询右表,右表中满足条件的显示出来,不满足条件的显示NULL。
我们还是用上面的例子来说明。其中emp表中“张三”这条记录中,部门编号为50,而dept表中不存在部门编号为50的记录,所以“张三”这条记录,不能满足e.deptno=d.deptno这条件。但在左连接中,因为emp表是左表,所以左表中的记录都会查询出来,即“张三”这条记录也会查出,但相应的右表部分显示NULL。
b.右外连接
右连接就是先把右表中所有记录都查询出来,然后左表满足条件的显示,不满足显示NULL。例如在dept表中的40部门并不存在员工,但在右连接中,如果dept表为右表,那么还是会查出40部门,但相应的员工信息为NULL。
SELECT * FROM emp e
RIGHT OUTER JOIN dept d
ON e.deptno=d.deptno;

连接查询心得:
连接不限与两张表,连接查询也可以是三张、四张,甚至N张表的连接查询。通常连接查询不可能需要整个笛卡尔积,而只是需要其中一部分,那么这时就需要使用条件来去除不需要的记录。这个条件大多数情况下都是使用主外键关系去除。
两张表的连接查询一定有一个主外键关系,三张表的连接查询就一定有两个主外键关系,所以在大家不是很熟悉连接查询时,首先要学会去除无用笛卡尔积,那么就是用主外键关系作为条件来处理。如果两张表的查询,那么至少有一个主外键条件,三张表连接至少有两个主外键条件。
5.2.3 子查询
一个select语句中包含另一个完整的select语句。
子查询就是嵌套查询,即SELECT中包含SELECT,如果一条语句中存在两个,或两个以上SELECT,那么就是子查询语句了。
l 子查询出现的位置:
a. where后,作为条为被查询的一条件的一部分;
b. from后,作表;
l 当子查询出现在where后作为条件时,还可以使用如下关键字:
a. any
b. all
l 子查询结果集的形式:
a. 单行单列(用于条件)
b. 单行多列(用于条件)
c. 多行单列(用于条件)
d. 多行多列(用于表)
示例:
1. 工资高于JONES的员工。
分析:
查询条件:工资>JONES工资,其中JONES工资需要一条子查询。
第一步:查询JONES的工资
SELECT sal FROM emp WHERE ename='JONES';
第二步:查询高于甘宁工资的员工
SELECT * FROM emp WHERE sal > (第一步结果);
结果:
SELECT * FROM emp WHERE sal > (SELECT sal FROM emp WHERE ename='JONES');
2. 查询与SCOTT同一个部门的员工。
l 子查询作为条件
l 子查询形式为单行单列
分析:
查询条件:部门=SCOTT的部门编号,其中SCOTT 的部门编号需要一条子查询。
第一步:查询SCOTT的部门编号
SELECT deptno FROM emp WHERE ename='SCOTT';
第二步:查询部门编号等于SCOTT的部门编号的员工
SELECT * FROM emp WHERE deptno = (SELECT deptno FROM emp WHERE ename='SCOTT');
3. 工资高于30号部门所有人的员工信息
分析:
SELECT * FROMemp WHERE sal>(SELECT MAX(sal)FROM emp WHERE deptno=30);
查询条件:工资高于30部门所有人工资,其中30部门所有人工资是子查询。高于所有需要使用all关键字。
第一步:查询30部门所有人工资
SELECT sal FROM emp WHERE deptno=30;
第二步:查询高于30部门所有人工资的员工信息
SELECT * FROM emp WHERE sal > ALL (第一步)
结果:
SELECT * FROM emp WHERE sal > ALL (SELECT sal FROM emp WHERE deptno=30)
l 子查询作为条件
l 子查询形式为多行单列(当子查询结果集形式为多行单列时可以使用ALL或ANY关键字)
第六章 综合练习
某网上商城数据库如下图所示
#一对多的实现
#创建分类表
create table category(
cid varchar(32) PRIMARY KEY ,
cname varchar(100) #分类名称
);
# 商品表
CREATE TABLE `products` (
`pid` varchar(32) PRIMARY KEY ,
`name` VARCHAR(40) ,
`price` DOUBLE
);
#添加外键字段
alter table products add column category_id varchar(32);
#添加约束
alter table products add constraint product_fk foreign key (category_id) references category (cid);
#多对多的实现
#订单表
create table `orders`(
`oid` varchar(32) PRIMARY KEY ,
`totalprice` double #总计
);
# 订单项表
create table orderitem(
oid varchar(50), #订单id
pid varchar(50) #商品id
);
#联合主键(可省略)
alter table `orderitem` add primary key (oid,pid);
# 订单表和订单项表的主外键关系
alter table `orderitem` add constraint orderitem_orders_fk foreign key (oid) references orders(oid);
# 商品表和订单项表的主外键关系
alter table `orderitem` add constraint orderitem_product_fk foreign key (pid) references products(pid);
#初始化数据
#给商品表初始化数据
insert into products(pid,name,price,category_id) values('p001','联想',5000,'c001');
insert into products(pid,name,price,category_id) values('p002','海尔',3000,'c001');
insert into products(pid,name,price,category_id) values('p003','雷神',5000,'c001');
insert into products(pid,name,price,category_id) values('p004','JACK JONES',800,'c002');
insert into products(pid,name,price,category_id) values('p005','真维斯',200,'c002');
insert into products(pid,name,price,category_id) values('p006','花花公子',440,'c002');
insert into products(pid,name,price,category_id) values('p007','劲霸',2000,'c002');
insert into products(pid,name,price,category_id) values('p008','香奈儿',800,'c003');
insert into products(pid,name,price,category_id) values('p009','相宜本草',200,'c003');
insert into products(pid,name,price,category_id) values('p010','梅明子',200,null);
#给分类表初始化数据
insert into category values('c001','电器');
insert into category values('c002','服饰');
insert into category values('c003','化妆品');
insert into category values('c004','书籍');
6.1 综合练习-【多表查询】
1>查询用户的订单,没有订单的用户不显示
2>查询所有用户的订单详情
3>查询所有订单的用户详情
6.2 综合练习2-【子查询】
1>查看用户为张三的订单详情
2>查询出订单的价格大于300的所有用户信息。
3>查询订单价格大于300的订单信息及相关用户的信息。
6.2 综合练习3-【分页查询】
总结
作业题
数据库结构
创建四张表 分别存储 学生信息 课程信息 分数 讲师信息表 存储相应数据
学生信息表 Student
字段名 字段类型 字段约束 / 含义
Sno Varchar(3) Not null / 学员编号
Sname Varchar(4) Not null / 学员姓名
Ssex Varchar(2) Not null / 性别
Sbirthday Datetime 生日
Classnum Varchar(5) 班级号
CREATE TABLE STUDENT
(
SNO VARCHAR(3) NOT NULL,
SNAME VARCHAR(4) NOT NULL,
SSEX VARCHAR(2) NOT NULL,
SBIRTHDAY DATETIME,
CLASS VARCHAR(5)
)
课程信息表 course
字段名 字段类型 字段约束 / 含义
Cno Varchar(5) Not null / 课程编号
Cname Varchar(10) Not null / 课程名称
Tno Varchar(10) Not null / 授课老师编号
CREATE TABLE COURSE
(CNO VARCHAR(5) NOT NULL,
CNAME VARCHAR(10) NOT NULL,
TNO VARCHAR(10) NOT NULL)
成绩表score
字段名 字段类型 字段约束 / 含义
Sno Varchar(3) Not null / 学员编号
Cno Varchar(5) Not null / 课程编号
Degree Double(3,1) Not null / 分数
CREATE TABLE SCORE
(SNO VARCHAR(3) NOT NULL,
CNO VARCHAR(5) NOT NULL,
DEGREE NUMERIC(10, 1) NOT NULL)
讲师表teacher
字段名 字段类型 字段约束 / 含义
Tno Varchar(3) Not null / 讲师编号
Tname Varchar(4) Not null / 讲师姓名
Tsex Varchar(2) Not null / 讲师性别
Tbirthday Datetime Not null / 出生日期
Prof Varchar(6) 等级
Depart Varchar(10) 所属院系
CREATE TABLE TEACHER
(TNO VARCHAR(3) NOT NULL,
TNAME VARCHAR(4) NOT NULL, TSEX VARCHAR(2) NOT NULL,
TBIRTHDAY DATETIME NOT NULL, PROF VARCHAR(6),
DEPART VARCHAR(10) NOT NULL)
向表中存储数据
INSERT INTO STUDENT (SNO,SNAME,SSEX,SBIRTHDAY,CLASS) VALUES (108 ,'曾华' ,'男' ,1977-09-01,95033);
INSERT INTO STUDENT (SNO,SNAME,SSEX,SBIRTHDAY,CLASS) VALUES (105 ,'匡明' ,'男' ,1975-10-02,95031);
INSERT INTO STUDENT (SNO,SNAME,SSEX,SBIRTHDAY,CLASS) VALUES (107 ,'王丽' ,'女' ,1976-01-23,95033);
INSERT INTO STUDENT (SNO,SNAME,SSEX,SBIRTHDAY,CLASS) VALUES (101 ,'李军' ,'男' ,1976-02-20,95033);
INSERT INTO STUDENT (SNO,SNAME,SSEX,SBIRTHDAY,CLASS) VALUES (109 ,'王芳' ,'女' ,1975-02-10,95031);
INSERT INTO STUDENT (SNO,SNAME,SSEX,SBIRTHDAY,CLASS) VALUES (103 ,'陆君' ,'男' ,1974-06-03,95031);
GO
INSERT INTO COURSE(CNO,CNAME,TNO)VALUES ('3-105' ,'计算机导论',825)
INSERT INTO COURSE(CNO,CNAME,TNO)VALUES ('3-245' ,'操作系统' ,804);
INSERT INTO COURSE(CNO,CNAME,TNO)VALUES ('6-166' ,'数据电路' ,856);
INSERT INTO COURSE(CNO,CNAME,TNO)VALUES ('9-888' ,'高等数学' ,100);
GO
INSERT INTO SCORE(SNO,CNO,DEGREE)VALUES (103,'3-245',86);
INSERT INTO SCORE(SNO,CNO,DEGREE)VALUES (105,'3-245',75);
INSERT INTO SCORE(SNO,CNO,DEGREE)VALUES (109,'3-245',68);
INSERT INTO SCORE(SNO,CNO,DEGREE)VALUES (103,'3-105',92);
INSERT INTO SCORE(SNO,CNO,DEGREE)VALUES (105,'3-105',88);
INSERT INTO SCORE(SNO,CNO,DEGREE)VALUES (109,'3-105',76);
INSERT INTO SCORE(SNO,CNO,DEGREE)VALUES (101,'3-105',64);
INSERT INTO SCORE(SNO,CNO,DEGREE)VALUES (107,'3-105',91);
INSERT INTO SCORE(SNO,CNO,DEGREE)VALUES (108,'3-105',78);
INSERT INTO SCORE(SNO,CNO,DEGREE)VALUES (101,'6-166',85);
INSERT INTO SCORE(SNO,CNO,DEGREE)VALUES (107,'6-106',79);
INSERT INTO SCORE(SNO,CNO,DEGREE)VALUES (108,'6-166',81);
GO
INSERT INTO TEACHER(TNO,TNAME,TSEX,TBIRTHDAY,PROF,DEPART)
VALUES (804,'李诚','男','1958-12-02','副教授','计算机系');
INSERT INTO TEACHER(TNO,TNAME,TSEX,TBIRTHDAY,PROF,DEPART)
VALUES (856,'张旭','男','1969-03-12','讲师','电子工程系');
INSERT INTO TEACHER(TNO,TNAME,TSEX,TBIRTHDAY,PROF,DEPART)
VALUES (825,'王萍','女','1972-05-05','助教','计算机系');
INSERT INTO TEACHER(TNO,TNAME,TSEX,TBIRTHDAY,PROF,DEPART)
VALUES (831,'刘冰','女','1977-08-14','助教','电子工程系');
1、 查询Student表中的所有记录的Sname、Ssex和Class列。
2、 查询教师所有的单位即不重复的Depart列。
3、 查询Student表的所有记录。
4、 查询Score表中成绩在60到80之间的所有记录。
5、 查询Score表中成绩为85,86或88的记录。
6、 查询Student表中“95031”班或性别为“女”的同学记录。
7、 以Class降序查询Student表的所有记录。
8、 以Cno升序、Degree降序查询Score表的所有记录。
9、 查询“95031”班的学生人数。
10、查询Score表中的最高分的学生学号和课程号。
11、查询‘3-105’号课程的平均分。
12、查询Score表中至少有5名学生选修的并以3开头的课程的平均分数。
13、查询最低分大于70,最高分小于90的Sno列。
14、查询所有学生的Sname、Cno和Degree列。
15、查询所有学生的Sno、Cname和Degree列。
16、查询所有学生的Sname、Cname和Degree列。
17、查询“95033”班所选课程的平均分。
18、假设使用如下命令建立了一个grade表:
create table grade(low number(3,0),upp number(3),rank char(1));
insert into grade values(90,100,’A’);
insert into grade values(80,89,’B’);
insert into grade values(70,79,’C’);
insert into grade values(60,69,’D’);
insert into grade values(0,59,’E’);
commit;
现查询所有同学的Sno、Cno和rank列。
19、查询选修“3-105”课程的成绩高于“109”号同学成绩的所有同学的记录。
20、查询score中选学一门以上课程的同学中分数为非最高分成绩的记录。
21、查询成绩高于学号为“109”、课程号为“3-105”的成绩的所有记录。
22、查询和学号为108的同学同年出生的所有学生的Sno、Sname和Sbirthday列。
23、查询“张旭“教师任课的学生成绩。
24、查询选修某课程的同学人数多于5人的教师姓名。
25、查询95033班和95031班全体学生的记录。
26、查询存在有85分以上成绩的课程Cno.
27、查询出“计算机系“教师所教课程的成绩表。
28、查询“计算机系”与“电子工程系“不同职称的教师的Tname和Prof。
29、查询选修编号为“3-105“课程且成绩至少高于选修编号为“3-245”的同学的Cno、Sno和Degree,并按Degree从高到低次序排序。
30、查询选修编号为“3-105”且成绩高于选修编号为“3-245”课程的同学的Cno、Sno和Degree.
31、查询所有教师和同学的name、sex和birthday.
32、查询所有“女”教师和“女”同学的name、sex和birthday.
33、查询成绩比该课程平均成绩低的同学的成绩表。
34、查询所有任课教师的Tname和Depart.
35 查询所有未讲课的教师的Tname和Depart.
36、查询至少有2名男生的班号。
37、查询Student表中不姓“王”的同学记录。
38、查询Student表中每个学生的姓名和年龄。
39、查询Student表中最大和最小的Sbirthday日期值。
40、以班号和年龄从大到小的顺序查询Student表中的全部记录。
41、查询“男”教师及其所上的课程。
42、查询最高分同学的Sno、Cno和Degree列。
43、查询和“李军”同性别的所有同学的Sname.
44、查询和“李军”同性别并同班的同学Sname.
45、查询所有选修“计算机导论”课程的“男”同学的成绩表
面试题
有三张表,学生表S,课程C,学生课程表SC,学生可以选修多门课程,一门课程可以被多个学生选修,通过SC 表关联。【基础】
1)写出建表语句;
2)写出SQL 语句,查询选修了所有选修课程的学生;
3)写出SQL 语句,查询选修了至少5 门以上的课程的学生。
一、复习
重要的内容: 数据库,SQL(DDL,DML,DQL)
1、字符集的问题:
安装数据库的时候需要指定字符集
创建数据库也要指定字符集
创建表的时候也需要字符集
表中的字段也需要字符集
如果表中的字段创建时没有指定字符集,就跟表一致,如果创建表的时候没有指定,默认就跟数据库保持一致,
创建数据库时没有指定字符集,那么默认就跟安装数据库时指定的字符集保持一致。
2、DML语法
INSERT INTO 表名(列名1,列名2 …)VALUES(列值1,列值2…);
UPDATE 表名 SET 列名1=列值1,列名2=列值2 … WHERE 列名=值
update操作一般都会报随着一些条件的,不写条件就意味着全部更改,非常危险。
DELETE 表名 【WHERE 列名=值】 一般也伴随一个where条件,否则就是全部删除数据
TRUNCATE TABLE 表 名;
- DELETE 删除表中的数据,表结构还在;删除后的数据可以找回
- TRUNCATE 删除是把表直接DROP掉,然后再创建一个同样的新表。
- 删除的数据不能找回。执行速度比DELETE快。
3、DQL(重要事情说三遍)
SELECT selectionlist /要查询的列名称/
FROM table_list /要查询的表名称/
WHERE condition /行条件/
GROUP BY grouping_columns /对结果分组/
HAVING condition /分组后的行条件/
ORDER BY sorting_columns /对结果分组/
LIMIT offset_start, row_count /结果限定/
需要补充的点:
1)between 20 and 40 代表一个数值 大于等于20并且小于等于40,是包含边界的
2) id in(1,3,5) 表示 where id=1 or id=3 or id=5
id not in(1,3,5) 表示: id != 1 and id != 3 and id != 5
3) 模糊查询的语法
select 字段 from 表名 where 字段 like ‘%等内容’
like ‘‘ 代表占用任意一个字符
like ‘%a%’ %表示占用0到多个字符
最重要的场景:查询包含某个字符的所有数据 title like ‘%java%’
4) mysql 自带的函数:
IFNULL(comm,0) 表示:comm这个字段中的值如果是null,就用默认值0代替,如果不是null,就原样输出
MAX(age) 取出所有字段中年龄最大的值
MIN(age) 最小值 SUM(money) 将所有数据的money全部相加得到一个值
count(1) 统计数据有多少条 select count(1) from emp;
avg(score) 求数据中分数的平均分 now() 可以获取到mysql 服务器的当前时间
5) 排序 order by 字段名 asc/desc
根据某个字段进行升序或者降序的排列,如果不写升降的关键字,默认是升序的。
order by 后面如果跟多个字段,先按照字段1进行排序,如果字段1中出现了相同的数据,无法知道先后,再根据第二个字段排序
select * from emp order by salary desc,empno asc;
6) 分组 group by 字段 having 过滤
select deptno,sum(sal) from emp group by deptno having sum(sal)>5000;
注:having与where的区别:
1.having是在分组后对数据进行过滤,where是在分组前对数据进行过滤
2.having后面可以使用分组函数(统计函数) 分组函数不是指的分组,指的是sum(),count(),avg(),等用于统计的函数
where后面不可以使用分组函数。
WHERE是对分组前记录的条件,如果某行记录没有满足WHERE子句的条件,那么这行记录不会参加分组;而HAVING是对分组后数据的约束。
比如:
这样的SQL 是错误的:
SELECT deptno,max(sal)
FROM emp
WHERE MAX(sal) > 2900
GROUP BY deptno;
这样才是正确的:
SELECT deptno,max(sal)
FROM emp
GROUP BY deptno
HAVING MAX(sal) > 2900;
7)分页: limit 起始点从0开始,每页展示的总条数;
emp 中如果只有20条数据, select from emp limit 0,100;
//如果查询的数量超过了可以展示的数量,以实际的数量为准。
8)关于数据的一些备份与还原
dos命令下,找到mysql的bin目录,输入
mysqldump -u 用户名 -p密码 数据库名字> C:/文件名.sql
mysqldump -uroot -proot mydb01 > C:/mydb01202108241015.sql
还原:需要先登录mysql,创建好数据库
use 某个数据库;
source 导入的文件路径及名称
use mydb01;
source C:/xxxx.sql 回车执行
可以使用图形化工具导入导出数据。
9)windows常用的几个dos命令
快速打开服务列表: services.msc
打开计算器 : calc
画图工具 : mspaint
10) 蠕虫复制:
我们在工作过程中 如果遇到了要新建表,复制一个表数据的情况。
实战的角度讲:使用图形化界面复制 粘贴 速度要远胜于将数据导出来,再导入到本地要快。
蠕虫复制:将一张表中的数据复制到另一张表中
insert into 表名1 select from 表名2
也可以只复制其中几个列的数据:
insert into emp2(name,salary) select ename,sal from emp;
11) 数据库表字段的类型
float double decimal
sal float(10,2)
sal double(10,2)
sal decimal(10,2)
10代表的是整个数据长度总长为10,包含小数点后的2个长度 整数部分8为,小数部分2位
float double 属于浮点型 float属于单精度,double属于双精度
float 类型的数据,占用4个字节,double 占用8个字节
double可以表达的小数点后的长度要比float长。
尾数可以有 16 位,而 float 尾数精度只有 7 位
decimal 一般应用于金融领域,计算出来的数据是准确的
float和double求SUM的结果都是不精确的,只有decimal求SUM得到的是精准数值。
所以一般在我们进行一些金融产品开发的时候建议使用decimal这个数据类型。
如果你指定了数据类型是decimal,不指定长度的话,长度是10,小数是0 (10,0)
12) 查看表结构
desc 表名; 可以查看该表的表结构,横向展示的。
desc 表名\G 没有分号,直接回车,纵向展示表结构,一般黑窗口中出现,在图形化界面时不好使。
二、回顾
1、单表查询的一些补充
2、数据的备份与恢复
3、约束 主键、唯一、非空等约束,自增
4、多表
表关系(一对一,一对多,多对多)
一对一: A 表 ,B 表 在任何一个表中,添加一列当外键指向另一个表的主键就可以了
一对多: 在多 的一方,设计一个外键,指向一的一方的主键
多对 多: 需要创建中间表 将两个表中的主键抽取出来,放入到中间表中。
5、多表查询
多表查询: 内连接,外连接
三、子查询
子查询又称之为嵌套查询,一个SQL语句中,出现了另一个SQL语句。
1) 工资高于JONES的员工
select sal from emp where ename='JONES';
select * from emp where sal>2975;
合并:
select * from emp where sal>(select sal from emp where ename='JONES');
2) 查询与SCOTT同一个部门的员工
分析: SCOTT 他是哪个部分的,通过部门编号,找到对应的同事
select deptno from emp where ename='SCOTT';
select * from emp where deptno=20;
合并:
select * from emp where deptno=(select deptno from emp where ename='SCOTT');
3)工资高于30号部门所有人的员工信息
分析:30号部门,最高工资是多少,我们要取大于这个工资的员工信息
select max(sal) from emp where deptno=30;
select * from emp where sal>(select max(sal) from emp where deptno=30);
也可以使用all关键字:
select * from emp where sal> all(select sal from emp where deptno=30);
4、查询所有员工信息以及工资总和
select *,(select sum(sal) from emp) as '工资总和' from emp;
select *,(select sum(sal)+sum(IFNULL(comm,0)) from emp) as '工资总和' from emp;
5、查询工资最高TOP 5
select * from emp order by sal desc limit 5;
6、查询员工表中第6到第12条数据
select * from emp limit 5,7;
7、查询所有不是部门经理的员工<br /> 先把部门经理的编号给查询出来:
select distinct mgr from emp where mgr is not null;
select * from emp where empno not in(select distinct mgr from emp where mgr is not null);
8、查询所有员工人数不少于3人的部门信息<br /> 哪些部门,员工人数不少于3人呢?
select deptno from emp group by deptno having count(1)>3;
合并:
select * from dept where deptno in (select deptno from emp group by deptno having count(1)>3);
9、查询员工编号,姓名,部门编号,工资,本部门工资总和
select deptno,sum(sal)+sum(IFNULL(comm,0)) as money from emp group by deptno; // ss
以上的查询 结果当做一个新的虚拟 表 ss
select e.empno,e.ename,e.deptno,e.sal,ss.money from emp e , ss where e.deptno=ss.deptno;
select e.empno,e.ename,e.deptno,e.sal,ss.money from emp e,(select deptno,sum(sal)+sum(IFNULL(comm,0)) as money from emp group by deptno) ss where e.deptno=ss.deptno;
// 还有一种写法:
select empno,ename,deptno,sal,(select sum(sal) from emp e1 where e1.deptno=e2.deptno ) as money from emp e2;
10、查询每个员工的姓名和上级领导的姓名
select ename,(select ename from emp e1 where e1.empno=e2.mgr) as '上级领导' from emp e2;
