SQL语言的分类及语法
一、SQL语言的分类
1、DDL(Data Definition Language)数据定义语言(语法固定)
- 用来操作数据库和表
关键字:create(创建)、drop(删除)、alter(更改)等
2、DML (Data Manipulation Language)数据操作语言 (语法固定的)
- 用来对数据库中表的数据进行增删改
关键字:insert(增),delete(删), update(改)等
3、DQL(Data Query Language)数据查询语言 (语法千变万化的)
- 用来对数据库中表的数据进行查询
关键字:select,from,where等
4、TCL(Transaction Control Language) 事务控制语言
- 用于控制数据库的事务操作
关键字: commit,rollback等
5、DQL(Data Control Language)数据控制语言
- 用来定义数据库的访问权限和安全级别,及创建用户。
关键字:grant, revoke等
二、SQL语言的语法规则
1 SQL语句可以单行或多行书写,以分号结尾
2 可使用空格和缩进来增强语句的可读性
3 MySQL数据库的SQL语句不区分大小写
4 可以使用-- 或# 或/**/的方式完成注释
三、SQL语言的使用
1、DDL(数据定义语言)
1)操作数据库
- 创建数据库
create database 数据库名;(存在:报错 ; 不存在:创建)
create database if not exists 数据库名;(存在:不创建;不存在:创建) - 查询数据库
show databases; - 删除数据库
drop database 数据库名; - 其他操作
查看当前使用的数据库 select database();
切换数据库 use 数据库名;
2)操作表
- 条件:首先要进入到指定的数据库中 use 数据库名;
- 创建表 create
1.create table 表名(字段名1 字段类型,
字段名2 字段类型(长度));
只有字符串类型需要手动加长度,其它类型都不需要加长度(默认有)
2.快速创建表结构(复制表): create table 新表名 like 旧表名;
数据类型:
java的数据类型 mysql数据库的数据类型
int int
float float
double double
char/string varchar(字段长度)
date date yyyy-MM-dd
time HH:MM:SS
datetime YYYY-MM-DD HH:MM:SS
-- 需求: 创建一个学生表(id name sex cs)
create table stu(
id int,
name varchar(2),
sex varchar(1),
cs date
)
- 查看表 show
查看某个数据库中的所有表: show tables;
查看表结构: desc 表名称;
查询建表语句: show create table 表名; - 修改表结构 alert
添加表列 : alter table 表名 add 列名 类型;
修改列名 : alter table 表名 change 旧名称 新名称 类型;
修改列类型: alter table 表名 modify 列名 新类型
删除表列 : alter table 表名 drop 列名;
修改表名称: rename table 表名 to 新表名; - 删除表 drop
直接删除表: drop table 表名;
判断表是否存在并删除表(了解): drop table if exists 表名; 存在就删 不存在就不删了
2、DML(数据操作语言)
- 插入记录 insert
1.添加全部字段
insert into 表名 values (值1,值2,值3 …);
2.添加部分字段
insert into 表名(字段1,字段2)values(值1,值2)
3.蠕虫复制
在已有的数据基础之上,将原来的数据进行复制,插入到对应的表中
前提:表结构得一致 create table 新表名 like 旧表名;
语法格式: insert into 新表名 select * from 旧表名;
4.注意事项
1.值与字段必须对应,个数相同,类型相同
2.值的数据大小必须在字段的长度范围内
3.除了数值类型外,其它的字段类型的值必须使用引号引起。
4.如果要插入空值,可以不写字段,或者手动插入null
- 修改记录
1.不带条件修改(全改)update 表名 set 字段1=值1,字段2=值2;
2.带条件修改(指定条件修改)update 表名 set 字段1=值1,字段2=值2 where 字段=值; - 删除记录
1.不带条件删除数据: delete from 表名; 特点:全删
2.根据条件删除数据: delete from 表名 where 字段名=值; 特点:按条件删
truncate删除表记录: truncate table 表名; 全删
truncate和delete的区别:
delete是将表中的数据一条一条删除
truncate是将整个表摧毁,重新创建一个新的表,新的表结构和原来表结构一模一样
delete删除的数据能够找回 truncate删除的数据找不回来了
3、DQL(数据查询语言)☆☆☆☆☆☆
1)、案例
#创建商品表:
create table product(
pid int,
pname varchar(20),
price double,
category_id varchar(32)
);
insert into product values(1,'联想',5000,'c001');
insert into product values(2,'海尔',3000,'c001');
insert into product values(3,'雷神',5000,'c001');
insert into product values(4,'JACK JONES',800,'c002');
insert into product values(5,'真维斯',200,'c002');
insert into product values(6,'花花公子',440,'c002');
insert into product values(7,'劲霸',2000,'c002');
insert into product values(8,'香奈儿',800,'c003');
insert into product values(9,'相宜本草',200,'c003');
insert into product values(10,'面霸',5,'c003');
insert into product values(11,'好想你枣',56,'c004');
insert into product values(12,'香飘飘奶茶',null,'c005');
insert into product values(13,'果9',1,null);
insert into product values(14,'香飘飘奶茶','c005');
简单查询
- 查询所有列 select * from 表名;
#1.查询所有的商品.
select * from product;
- 查询指定列 select 字段名1,字段名2… from 表名;
#2.查询商品名和商品价格.
select pname,price from product;
- 别名查询 select 字段名1 as 别名,字段名2 as 别名… from 表名 as 别名;
#3.别名查询.使用的关键字是as(as可以省略的)
select pname as 商品名,price as 价格 from product as 产品;
- 清除重复值查询 select distinct 字段名 from 表名;
#4.查看商品表中有那些价格(去重复)
select distinct price as 价格 from product;
- 查询结果参与运算 select 字段名+固定值 from 表名;
(参与运算的字段必须为数值型)
#5.将所有商品的价格+10元进行显示
#mysql函数:ifnull(要判断的字段,要给的值)
select pname 名称,IFNULL(price,0) 现价,IFNULL(price,0)+10 原价 from product;
条件查询
- select * from 表名 where 条件;
where可以加的条件运算符
> 大于
< 小于
<= 小于等于
>= 大于等于
= 等于
<> 、 != 不等于
and(&&),between..and 多个条件同时满足
or(||) in 多个条件其中一个满足
not(!) 不满足
-- sql语言:DQL 做表上数据的查询语句
#条件查询(条件后的大量运算符)
#查询商品名称为“花花公子”的商品所有信息:
select * from product where pname="花花公子";
#查询价格为800商品
select * from product where price=800;
select * from product where price>800;
select * from product where price<800;
#查询价格不是800的所有商品
select * from product where price !=800;
select * from product where price <>800;
#查询商品价格大于等于60元的所有商品信息
select * from product where price>=440;
select * from product where price<=440;
#查询商品价格在200到1000之间所有商品
select * from product where price>=200 and price<=1000;
select * from product where price>=200 && price<=1000;
select * from product where price between 200 and 1000; -- 数据库写法
#查询商品价格是200或800的所有商品
select * from product where price=200 or price=800;
select * from product where price=200 || price=800;
select * from product where price in(200,800,1000,2000);
select * from product where price not in(200,800,1000,2000); -- 数据库写法
模糊查询
- like ( % : 模糊多位)😭 _ : 模糊一位)
展示
-- sql语言:DQL 做表上数据的查询语句
#模糊查询 like % 匹配多位 _ 匹配一位
#查询含有'霸'字的所有商品 面面霸面
select * from product where pname like "%霸%";
#查询以'香'开头的所有商品
select * from product where pname like "香%";
#查询第二个字为'想'的所有商品
select * from product where pname like "_想%";
#商品没有分类的商品 空值不能用等于 只能用is
select * from product where category_id is null;
#查询有分类的商品
select * from product where category_id is not null;
2)、案例
create table student(
id int,
name varchar(20),
age int,
sex varchar(5),
address varchar(100),
math int,
english int
);
insert into student(id,name,age,sex,address,math,english) values (1,'马云',55,'男','杭
州',66,78),(2,'马化腾',45,'女','深圳',98,87),(3,'马景涛',55,'男','香港',56,77),(4,'柳
岩',20,'女','湖南',76,65),(5,'柳青',20,'男','湖南',86,null),(6,'刘德华',57,'男','香港',99,99),
(7,'马德',22,'女','香港',99,99),(8,'德玛西亚',18,'男','南京',56,65);
排序查询
- select * from 表名 where 条件 order by 字段名[desc|asc],字段名[desc|asc];
- asc(默认):升序 desc:降序
展示
# 查询所有数据,使用年龄降序排序
select * from student order by age asc;
select * from student order by age desc;
#查询所有数据,在年龄降序排序的基础上,如果年龄相同再以数学成绩降序排序
select * from student order by age desc,math desc;
聚合函数查询
- count() : 计数
- sum() : 求和
- max() : 求最大值
- min() : 求最小值
- avg() : 求平均值
展示
#查询学生总数
select COUNT(*) from student;
#查询年龄大于40的总数
select COUNT(*) from student where age>40;
#查询数学成绩平均分
select AVG(math) from student;
#查询数学成绩最高分
select MAX(math) from student;
#查询数学成绩最低分
select MIN(math) from student;
#查询数学成绩总和分
select SUM(math) from student;
select SUM(english) from student;
分组查询
- select * from 表名 where 条件 group by 分组字段 [having 分组条件 ] ;
having与where的区别(面试题)
having是在分组后对数据进行条件过滤.
where是在分组前对数据进行条件过滤
having后面可以使用聚合函数
where后面不可以使用聚合函数
展示
#分组查询 group by 字段
#特点1:查询分组数据:select查询的字段只能是聚合和分组的那个字段
#特点2:分组后要做条件得使用having 不能使用where
#按性别分组
select sex from student group by sex;
#查询男女各多少人
select COUNT(*),sex from student group by sex;
#查询年龄大于25岁的人,按性别分组,统计每组的人数
select sex,COUNT(*) from student where age>20 group by sex;
#查询年龄大于25岁的人,按性别分组,统计每组的人数,并只显示总人数大于2的数据
select sex,COUNT(*) from student where age>25 group by sex having COUNT(*)>2;
分页查询
- select * from 表名 limit 起始数,查询几条;
展示
#分页查询 limit a,b a:起始数据(不含头) b:查几条
#第一页的数据
select * from student limit 0,3;
#第二页的数据
select * from student limit 3,3;
#第三页的数据
select * from student limit 6,3;
查询顺序
- select distinct/列名/*/聚合 from 表 where 条件/运算符/模糊 group by having 条件 order by limit a,b
3)、 单表数据库约束
约束:对表中的数据可以进行进一步的限制,来保证数据的唯一性,正确性和完整性
约束种类:
- PRIMARY KEY : 主键约束 代表该字段的数据不能为空且不可重复
- NOT NULL : 非空 代表该字段的数据不能为空
- UNIQUE : 唯一 代表该字段的数据不能重复
数据库备份与还原### 主键约束 primary key
一个表中都得需要主键约束 用来标注一条记录的唯一性
特征:
主键字段值唯一不可重复
主键列不能包含NULL值
一个表中只能有一个主键,但主键可以是多个字段 (联合主键)
实现方式:
添加主键
方式一 在创建表时,添加约束
格式
create table 表名 (
字段名称1 字段类型 约束,
字段名称2 字段类型 约束
);
方式二 在创建表时,结尾内添加约束
格式1:单一主键
create table 表名 (
字段名称1 字段类型,
字段名称2 字段类型,
primary key(字段名称1)
);
格式2:联合主键
create table 表名 (
字段名称1 字段类型,
字段名称2 字段类型,
primary key(字段名称,字段名称1)
);
删除主键
alter table 表名 drop PRIMARY KEY;
主键自增
自己去维护主键过于麻烦,可以让数据库帮助我们去维护
auto_increment
默认地AUTO_INCREMENT 的开始值是1,如果希望修改起始值,请使用下列SQL语法
ALTER TABLE 表名 AUTO_INCREMENT=起始值;
唯一约束: unique
特征
被修饰的字段唯一,不可重复
注意: 一个表中可以有多个被unique修饰的字段,但对null不起作用
实现方式
创建表时在字段后添加
create table 表名 (
字段名称1 字段类型 约束,
字段名称2 字段类型 约束
);
非空约束: not null
特征:
被修饰的字段不可为空
实现方式
直接在字段后面添加即可
default : 默认值
4)、多表关系与约束
一对多
实现:分类表和商品表
称一的一方为主表 称多的一方为从表
原则:在从表中(多的一方)创建一个字段为外键,然后让这个外键指向主表的(一的一方)主键
数据库提供了外键约束的语法来实现指向关系:
关系建立: alter table 从表 add constraint [外键名称] foreign key (从表外键字段名) references 主表 (主表的主键)
关系删除: alter table 从表 drop foreign key 外键名称
外键约束的作用:能够保证数据的完整性和有效逻辑性
特征:从表中如果关联了主表的数据则强制主表的数据不能删除,保证数据的完整性和有效逻辑性
多对多
实现:学生表和课程表
原则:需要在外部创建一张中间表
这个中间表至少需要2个字段,然后让这2个字段(不能有唯一约束)分别作为外键只向各自表的主键
本质上就是两个一对多,添加中间表
一对一
人和身份证号,企业和法人
实现方式,一般都写在一张表中
如果非要拆分成两张表,可以有2种方式来建立它们之间的一对一关系
实现:
1 让双方的主键作为外键一一对应
2 在任意一方创建一个字段当成是外键指向另一方的主键,但是这个外键必须唯一约束unique
多表约束:外键约束
添加外键约束
方式1: 在已有表上添加外键约束
给从表的外键字段添加外键约束
alter table 从表 add [constraint 名称] foreign key(外键字段) references 主表名称(主键字段)
方式2:可视化图形方式(推荐)
在架构设计器中,直接指定外键拖向主键即可,简单方便快捷
删除外键
方式一:ALTER TABLE 从表 drop foreign key 外键名称;
方式二:在架构设计器中,选中指向关系右键删除即可
多表查询
多表查询:从多张表中获取到有关系的数据
比如:查询分类信息以及分类下的所有商品
多表查询的语法分类:
1.交叉查询(避免的)
2.内连接查询
隐式内连接
显示内连接
3.外连接查询
左外连接连接
右外连接查询
4.子查询
交叉连接(了解)
- select * from 表1,表2;
会产生2张表的乘积数据,简称笛卡尔积数据
我们发现这种方式查询出来的数据对我们来说没有任何意思
对于多表查询来说:我们最终要得到的数据其实是2张表有关系的数据
那么对于有关系的数据我们只能通过条件筛选,过滤掉没有关系的数据
所以:条件过滤对多表查询致关重要
条件过滤:可以寻找2张表之间有关联的字段进行过滤
内连接查询
特点:可以使用内连接去查询2张表之间有关系的数据
隐式内连接:
语法格式:select * from 表1,表2 where 关联条件 and 普通条件;
ps:可以使用表别名简化书写
显示内连接
语法格式:select * from 表1 [inner] join 表2 on 关联条件筛选 where 普通条件 and 普通条件 …;
on: 后跟的是关联条件
where: 后跟的是对结果的普通条件
需求 :查询唐僧的信息,显示员工id,姓名,性别,工资和所在的部门名称
隐式内连接:
select e.*,d.name from emp e,dept d where e.dept_id=d.id and e.name='唐僧';
显示内连接:
select e.*,d.name from emp e join dept d on e.dept_id=d.id where e.name='唐僧';
外连接查询
左外连接: 以join 左边的表为主,查询出来的是2张表之间有关系的数据以及左边表所有的数据
如果右表中没有满足条件的对应数据,则填充 null
语法格式:select * from 表1 left [outer] join 表2 on 关联条件 where 筛选条件;
右外连接: 以join 右边的表为主,查询出来的是2张表之间有关系的数据以及右边表所有的数据
如果左表中没有满足条件的对应数据,则填充null
语法格式:select * from 表1 rigth [outer] join 表2 on 关联条件 where 筛选条件;
需求1 :查询部门表和员工表有关系的数据,以及部门表没关系的数据
左外:
select * from dept d left join emp e on d.id=e.dept_id;
右外:
select * from emp e right join dept d on d.id=e.dept_id;
需求2 :查询员工表和部门表有关系的数据,以及员工表没关系的数据
左外:
select * from emp e left join dept d on d.id=e.dept_id;
右外:
select * from dept d right join emp e on d.id=e.dept_id;
子查询
可以做自关联数据查询(A-A)和多表数据查询(A-B) (有关系的数据)
用处1:一条sql执行的结果是另一条sql的条件,适用于单列单值或者单列多值
单列单值: select * from 表名 where (子查询结果)
单列多值: select * from 表名 where (子查询结果)
需求:
1 查询工资最高的员工是谁 (结果是单列单值)
#1.1 先查询最高的工资
select MAX(salary) from emp;
#1.2 再查询最高工资的员工
select name from emp where salary=(select MAX(salary) from emp);
2 查询工资小于平均工资的员工有哪些 (结果是单列单值)
#2.1 先查询平均工资
select AVG(salary) from emp;
#2.2 再查询小于平均工资的员工
select name from emp where salary<=(select AVG(salary) from emp);
3 查询工资大于5000的员工部门ID,来自于哪些部门(结果是单列多值)
#3.1 先查询工资大于5000的员工部门ID
select dept_id from emp where salary>5000;
#3.2 根据部门id获取部门名称
select name from dept where id in (select dept_id from emp where salary>5000);
4 查询开发部与财务部所有的员工信息(结果是单列多值)
#4.1 查询开发部与财务部的id
select id from dept where name in ('开发部','财务部');
#4.2 根据id获取员工信息
select name from emp where dept_id in (select id from dept where name in ('开发部','财务部'));
用处2:一条sql执行的结果作为一张表存在,适用于多列多值
多列多值: select * from 表名,(子查询结果) 表名2 where 条件
需求:
查询出2011-01-01以后入职的员工信息,包括部门名称(结果是多列多值)
select l.*,d.name from dept d,(select * from emp where join_date>'2011-01-01') l
where d.id=l.dept_id;