DDL:操作数据库、表
操作数据库:CRUD
- C(Creat): 创建
创建数据库
create database 要创建的数据库名称;
如果数据库不存在,创建数据库
create database if not exists 数据库名称;
注意:数据库创建出来,默认字符集为utf-8
如果要创建字符集为其他的数据库,则:
创建数据库指定字符集
create database 数据库名称 character set gbk(或其他字符集名称);
创建一个数据库,判断是否存在,并指定字符集
create database if not exists 数据库名称 character set gbk(或其他字符集名称);
- R(Retrieve):查询
查询所有数据库的名称
show databases;(建议使用大写)
查看某个数据库的字符集(查看某个数据库的创建语句)
show create database 数据库名称;
- U(Update):修改
修改数据库的字符集
alter database 数据库名称 character set 字符集名称;
- D(Delete):删除
删除数据库
drop database 数据库名称;(非常危险,没事别干!)
删除数据库并判断是否存在
drop database if exists 要删除数据库名称;
- 使用数据库
查询当前正在使用的数据库名称
select database();
使用数据库
use 数据库名称;
操作表:
- C(Creat):创建
- 语法:
create table 表名(
列名1 数据类型1,
列名2 数据类型2,
…………
列名n 数据类型n
);
** 注意:最后一列不需要加逗号!**
数据类型:
-
int:整数类型
-
double:小数类型
-
date:日期,只包含年月日,yyyy-MM-dd
-
datetime:日期,包含年月日时分秒,yyyy-MM-dd HH:mm:ss
-
timestamp:时间戳类型 包含年月日时分秒,yyyy-MM-dd HH:mm:ss
如果将来不给这个字段赋值,或赋值为null,则默认使用当前的系统时间来自动赋值 -
varchar:字符串类型
例如: name varchar(20) 表示:姓名最大20个字符
注意:zhangsan 8个字符,张三 2个字符- 创建表
create table student(
name varchar(32),
age int,
score double(4,1),
birthday date,
insert_time timestamp
);
复制表
create table 新表名 like 被复制的表名;
- R(Retrieve):查询
查询某个数据库中所有的表名称
show tables;
查询表结构
desc 表名;
-
U(Update):修改
1. 修改表名
alter table 原表名 rename to 新表名;
2. 修改表的字符集
show create table 表名 character set uft8(或其他字符集名称);
3. 添加一列
alter table 表名 add 列名 数据类型;
4. 修改列名称 类型
alter table 表名 change 原列名 新列名 新数据类型;
只改数据类型
alter table 表名 modify 列名 新数据类型;
5. 删除列
alter table 表名 drop 列名; -
D(Delete):删除
drop table 表名;
drop table if exists 表名;
DML:增删改表中数据
-
添加数据:
语法:
insert into 表名(列名1,列名2,……列名n) values(值1,值2,……值n);
注意:
1. 列名要和值一一对应。
2. 如果表名后,不定义列名,则默认给所有列添加值
3. 除了数字类型,其他类型需要使用引号(单双号都可以)引起来-
删除数据:
语法:
delete from 表名 where 条件;
注意:
1. 如果不加条件,则删除表中所有记录。
2. 如果要删除所有记录:
1. delete from 表名;
表中有多少条数据就执行多少次语句,不建议这样
2. 推荐使用
truncate table 表名; – 先删除表,然后再创建一个一摸一样的空表 -
修改数据:
语法:
update 表名 set 列名1 = 值1,列名2 = 值2,…… where 条件;
注意:
1. 如果不加条件,则会将表中所有记录都修改。
-
这里发现一个问题:添加时间那一列本来按照时间戳类型应该自动赋值为当前系统时间的
但是在我操作时发现并没有,于是通过搜索引擎找到了解决方法:
ALTER TABLE 表名 ADD COLUMN 列名 TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;
DQL:查询表中的记录
1.语法:
select
字段列表
from
表名列表
where
条件列表
group by
分组字段
having
分组之后的条件
order by
排序
limit
分页限定
- 基础查询:
-
多个字段的查询
有这么一个表: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 表名;
查询所有字段列表
select * from 表名;(或者一个一个将字段列表写出,方便阅读)
查询某个(些)字段列表
select 字段列表1,字段列表2,……字段列表n from 表名; -
去重
去除重复的结果集
关键字:distinct
select distinct 字段列表 from 表名;
有时候会发现去重不完全,有可能是因为数据格式不同(存在空字符)。
-
注意:
1. 如果有两个或以上字段列表去重,只有两个记录完全相同才可以去重。
3. 计算列
一般可以使用四则运算来计算一些列的值(一般只会进行数值型的计算)
select 字段列表1,字段列表2,……字段列表n, 运算 from 表名;
这里就有一个问题:
有null参与的运算,计算结果都为null。
解决:运用 ifnull(可能为null的字段,替换的值)
select 字段列表1,字段列表2,……字段列表n,a(±*/)ifnull(b,0) from student;
4. 起别名
上面的问题解决后,其中“math + ifnull(english,0)”字段名称原样显示,不好看
于是:
select name,math,english,math + ifnull(english,0) as(可不写) 别名 from student;
- 条件查询
1. where字句后跟条件
2. 运算符
>、<、<=、>=、=、<>(在SQL中表示不等于,在SQL中,没有==)
and 或 &&
or 或 ||
not或!
查询年龄等于(不等于、大于、小于……)20岁
select * from student where age=(> < >= <= <>)20;
between…and
查询年龄大于等于20,小于等于30
select * from student where age >=20 && age <=30;
select * from student where age >=20 and age <=30;
select * from student where age between 20 and 30;
in(集合)
查询22、18、25岁的信息
select * from student where age=22||age=18||age =25;
select * from student where age in (22,18,25);
like: – 模糊查询
占位符:
1. _:单个任意字符
2. %:多个任意字符
查询姓马的有哪些?
select * from student where name like '马%';
查询第二个字是化的人
select * from student where name like ‘_化%’;
查询姓名是3个字的人
select * from student where name like '___';
注意:如果出现两个字的人名,有可能是出现了空字符。
查询姓名中包含德的有哪些?
select * from student where name like '%德%';
is null
查询没有英语成绩的(成绩为null)
select * from student where English is null;
* 查询英语成绩不为null*
select * from student where English is not null;
- 查询语句
-
排序查询
语法:order by 排序字段1 排序方式1,排序字段2 排序方式2…
select * from student order by math desc;
select * from student order by math;
会发现虽然没有写排序方式,但是默认从小到大排序。
排序方式:
ASC:升序排列,默认的。
DESC:降序排列。按照数学成绩排名,如果数学成绩一样,则按照英语成绩排名
SELECT * FROM student ORDER BY math DESC,english DESC;
注意:
如果有多个排序条件,只有第一条件值相同时才会判断第二条件。 -
聚合函数:
将一列数据作为一个整体,进行纵向的计算。
SELECT 聚合函数(需要计算的那一列的名称) FROM 表名;
算出的结果是单行单列的。- count:计算个数
SELECT COUNT(列名) FROM 表名;- 一般选择非空的列:主键(推荐)
- count(*):只要这一行数据有一个不为null,那么它就能算一条记录。
- max:计算最大值
SELECT MAX(列名) FROM 表名; - min:计算最小值
SELECT MIN(列名) FROM 表名; - sum:计算和
SELECT SUM(列名) FROM 表名; - avg:计算平均值
SELECT AVG(列名) FROM 表名;
注意:
所有的聚合函数计算都排除了null的值。
解决方案:- 使用IFNULL函数:
SELECT COUNT(IFNULL(english,0)) FROM student; - 选择不包含null的列进行计算。(推荐)
- 使用IFNULL函数:
- count:计算个数
-
分组查询
统计一个具有相同特征的某一类数据,把这一类数据当做一个整体来看它们一些整体的信息。
1. 语法:
group by 分组字段;
** – 按照性别分组,分别查找男、女同学的数学、英语平均成绩**
SELECT sex ,AVG(math),AVG(english) FROM student GROUP BY sex;
where
– 按照性别分组,分别运用聚合函数
SELECT sex ,COUNT(id),AVG(math),MAX(math),MIN(math),SUM(math),AVG(english),MAX(english),MIN(english),SUM(english) FROM student GROUP BY sex;
** – 按照性别分组,分别查找男、女同学的平均分,人数且分数低于70分的人,不参与分组**
SELECT sex ,COUNT(id),AVG(math),AVG(english) FROM student WHERE math > 70 GROUP BY sex;
having
– 按照性别分组,分别查找男、女同学的平均分,人数且分数低于70分的人,不参与分组,分组之后,人数要大于2人。
SELECT sex ,COUNT(id),AVG(math),AVG(english) FROM student WHERE math > 70 GROUP BY sex HAVING COUNT(id)>2;
2. 注意:
1. 分组之后查询的字段有两个:分组字段、聚合函数,写其他字段没有任何意义。
2. where和having的区别?- where在分组之前进行限定,如果不满足条件,则不参与分组,having在分组后进行限定,如果不满足结果,这不会被查询出来。
- where后不可以跟聚合函数,而having可以进行聚合函数的判断。
-
分页查询
1. 语法:limit 开始的索引,每页查询的条数;
每页显示三条记录
SELECT * FROM student LIMIT 0,3; – 第一页
SELECT * FROM student LIMIT 3,3; – 第二页
SELECT * FROM student LIMIT 6,3; – 第三页
2. 公式:开始的索引=(当前的页码 - 1) * 每页显示的条数
3. limit是一个“方言”,只能在MySQL中使用。
-