小言_互联网的博客

MySQL基础语句总结

440人阅读  评论(0)

基本介绍

数据库可以持久化数据到本地,结构化查询。

三个基本名词:

  • DB:数据库,存储数据的容器
  • DBMS:数据库管理系统,又称为数据库软件或数据库产品,用于创建或管理DB
  • SQL:结构化查询语言,用于和数据库通信的语言,不是某个数据库软件特有的,而是几乎所有的主流数据库软件通用的语言

数据库存储数据的特点:

  • 数据存放到表中,然后表再放到库中

  • 一个库中可以有多张表,每张表具有唯一的表名用来标识自己

  • 表中有一个或多个列,列又称为“字段”,相当于java中“属性”

  • 表中的每一行数据,相当于java中“对象”

SQL语言的分类

DML(Data Manipulation Language):数据操纵语句,用于添加、删除、修改、查询数据库记录,并检查数据完整性。包括如下SQL语句:

  • INSERT:添加数据到数据库中。
  • UPDATE:修改数据库中的数据。
  • DELETE:删除数据库中的数据。
  • SELECT:选择(查询)数据。

DDL(Data Definition Language):定义数据库的结构,比如创建、修改或删除数据库对象,包括如下SQL语句:

  • CREATE TABLE:创建数据库表
  • ALTER TABLE:更改表结构、添加、删除、修改列长度
  • DROP TABLE:删除表
  • CREATE INDEX:在表上建立索引
  • DROP INDEX:删除索引

DCL(Data Control Language):数据控制语句,用于定义用户的访问权限和安全级别。包括如下SQL语句:

  • GRANT:授予访问权限

  • REVOKE:撤销访问权限

  • COMMIT:提交事务处理

  • ROLLBACK:事务处理回退

  • SAVEPOINT:设置保存点

  • LOCK:对数据库的特定部分进行锁定

基本的命令

首先是数据库的下载,Windows平台下下载:http://dev.mysql.com/downloads/mysql

下载安装后,可以——右击计算机—管理—服务—启动或停止MySQL服务。但是座位于i个程序员,这种方式也太low了,所以这几个命令可以看看:

  • 启动:net start mysql服务名

  • 停止:net stop mysql服务名

  • 登录 mysql [-h 主机名 -P 端口号] –u用户名 –p密码,[]这个是可选的,用于远程连接。

  • 退出 exit

一个基本的操作流程

  1. 进入 mysql, 在命令行中输入: mysql –uroot –p#### (其中:####表示密码)

  1. 查看 mysql 中有哪些个数据库: show databases;

  1. 使用一个数据库: use 数据库名称;

  2. 新建一个数据库: create database 数据库名

  3. 查看指定的数据库中有哪些数据表: show tables;

  4. 建表。

  5. 查看表的结构:desc 表名

  6. 删除表: drop table 表名

这是对数据库以及表的一些基本的操作命令,只展示两张基本操作截图,其他操作可以自行测试。

然后就是对表的数据经行基本的操作:

  1. 查看表中的所有记录: select * from 表名;

  2. 向表中插入记录:insert into 表名(列名列表) values(列对应的值的列表);

  1. 注意:插入 varchar 或 date 型的数据要用 单引号 引起来

  2. 修改记录: update 表名 set 列1 = 列1的值, 列2 = 列2的值 where …

  3. 删除记录: delete from 表名 where ….

这大概就是一个最基本的操作了,详细的操作将在下面展开。

DML语句

上面也基本说明了DML就是对数据(也就是表)的基本操作。

SELECT 语句

查询应该是使用最为频繁的一种操作了。数据库的优化,也基本上就是对查询的优化。

基础查询

基本的语法

select 查询列表 from 表名;。例如:select * from student;这就是对student查询所有的数据。

  • 查询列表可以是字段、常量、表达式、函数,也可以是多个
  • 查询结果是一个虚拟表

查询单个字段:select 字段名 from 表名;。例如:select name,age from student;只查询这两个字段。

特别注意:

  • SQL 语言大小写不敏感。
  • SQL 可以写在一行或者多行
  • 关键字不能被缩写也不能分行
  • 各子句一般要分行写。
  • 使用缩进提高语句的可读性。

查询的时候可以给查询到的列取一个别名,方便数据的展示。

规则:紧跟列名,也可以在列名和别名之间加入关键字 ‘AS’,别名使用双引号,以便在别名中包含空格或特殊的字符并区分大小写。

例如:select name as studentName,age "studentAge" from student;

去重查询,有时候不需要重复的数据就可以使用关键字来对这个数据去重,语法如下:
select distinct 字段名 from 表名;

带条件的查询

使用WHERE 子句,将不满足条件的行过滤掉。WHERE 子句紧随 FROM 子句。语法如下:
select 查询列表 from 表名 where 筛选条件,例如:(只查询部门id为90的员工)

也可以加其他的比较运算符:

简单条件运算符:> < = <> != >= <= <=>安全等于

逻辑运算符:&& and || or ! not,如果有多个条件,可以使用逻辑运算符连接起来:

其它比较运算:

操作符 含义
BETWEEN ...AND... 在两个值之间 (包含边界)
IN(set) 等于值列表中的一个
LIKE 模糊查询
IS NULL 空值

使用 IS (NOT) NULL 判断空值,例如:select * from student where name is NULL

使用 BETWEEN 运算来显示在一个区间内的值:

使用 IN运算显示列表中的值:

模糊查询

使用 LIKE 运算选择类似的值,选择条件可以包含字符或数字:

  • % 代表零个或多个字符(任意个字符)。
  • _ 代表一个字符。

如下图,查询名字开头单词为S的,后面是啥都行,只要求开头为S,比如Ssdg也会被查询出来。

如果说上面这个例子%改为 _ ,那就变成了后面只能有一个字符。

‘%’和‘-’可以同时使用:select * from student where name like %进_

排序查询

基本语法:select 查询列表 from 表 where 筛选条件 order by 排序列表 【asc | desc】

  • asc :升序,如果不写默认升序。desc:降序
  • 排序列表 支持 单个字段、多个字段、函数、表达式、别名
  • order by的位置一般放在查询语句的最后(除limit语句之外)

如果最后不加DESC,默认就是ASC升序的方式。

如果我们的字段取了别名,使用这个字段排序就需要使用别名:(salary*12 扩大12倍)

如果使用多个字段排序,按照ORDER BY 列表的顺序排序。(也就是按照写在前面的排序,如果有相等的就在按照后面的字段再次排序)


比如这个,由于department_id后面没有DESC,所以默认按照这个字段升序排列,然后有相等的再按照后面的salary降序排列。

函数

分组函数作用于一组数据,并对一组数据返回一个值。

组函数类型:

  • AVG() 求平均值
  • COUNT() 求总量
  • MAX() 求最大值
  • MIN() 最小值
  • SUM() 求和

可以对数值型数据使用AVG 和 SUM 函数,可以对==任意数据类型(字符按照字典排序)==的数据使用 MIN 和 MAX 函数。

COUNT(*) 返回表中记录总数,适用于任意数据类型:

COUNT(expr) 返回expr不为空的记录总数。

分组查询

可以使用GROUP BY子句将表中的数据分成若干组,语法如下:

select 分组函数,分组后的字段
from 表
【where 筛选条件】
group by 分组的字段
【having 分组后的筛选】
【order by 排序列表】

在SELECT 列表中所有未包含在组函数中的列都应该包含 在 GROUP BY 子句中。

包含在 GROUP BY 子句中的列不必包含在SELECT 列表中,就比如上面这个例子中的department_id在select中就可以不写,但是结果不会包含这个列。

WHERE 子句中不能使用组函数

使用 HAVING 过滤分组:(跟where用法一样,作用域不同)

  • 行已经被分组。
  • 使用了组函数。
  • 满足HAVING 子句中条件的分组将被显示。

多表查询

多个表可以经行联合的数据查询并展示,语法如下:select 字段 from 表1,表2,...;

笛卡尔集会在下面条件下产生:(效率很低)

  • 省略连接条件
  • 连接条件无效
  • 所有表中的所有行互相连接

为了避免笛卡尔集, 可以在 WHERE 加入有效的连接条件。

  • 在 WHERE 子句中写入连接条件。
  • 在表中有相同列时,在列名之前加上表名前缀。

等值连接:

SELECT beauty.id,NAME,boyname FROM beauty ,boys
WHERE beauty.`boyfriend_id`=boys.id;

区分重复的列名

  • 使用表名前缀在多个表中区分相同的列。
  • 在不同表中具有相同列名的列可以用表的别名加以区分。
  • 如果使用了表别名,则在select语句中需要使用表别名代替表名
  • 表别名最多支持32个字符长度,但建议越少越好

连接 n个表,至少需要 n-1个连接条件。

内连接

基本的语法格式:(别名可取可不取)

select 查询列表
from 表1 别名
[inner] join 表2 别名 on 连接条件
where 筛选条件
group by 分组列表
having 分组后的筛选
order by 排序列表
limit 子句;

这种链接的特点:

  • 表的顺序可以调换
  • 内连接的结果=多表的交集
  • n表连接至少需要n-1个连接条件

举个例子:

#案例.查询名字中包含e的员工名和工种名(添加筛选)
SELECT last_name,job_title
FROM employees e
INNER JOIN jobs j
ON e.`job_id`=  j.`job_id`
WHERE e.`last_name` LIKE '%e%';

外连接

基本的语法格式:

select 查询列表
from 表1 别名
left|right|full [outer] join 表2 别名 on 连接条件
where 筛选条件
group by 分组列表
having 分组后的筛选
order by 排序列表
limit 子句;

这种连接的特点:

  • 查询的结果=主表中所有的行,如果从表和它匹配的将显示匹配行,如果从表没有匹配的则显示null
  • left join 左边的就是主表,right join 右边的就是主表,full join 两边都是主表
  • 一般用于查询除了交集部分的剩余的不匹配的行

举些例子:

#案例1:查询哪个部门没有员工,左外
SELECT d.*,e.employee_id
FROM departments d
LEFT OUTER JOIN employees e
ON d.`department_id` = e.`department_id`
WHERE e.`employee_id` IS NULL;
 
#右外
SELECT d.*,e.employee_id
FROM employees e
RIGHT OUTER JOIN departments d
ON d.`department_id` = e.`department_id`
WHERE e.`employee_id` IS NULL;

#全外
USE girls;
SELECT b.*,bo.*
FROM beauty b
FULL OUTER JOIN boys bo
ON b.`boyfriend_id` = bo.id;

John连接总结

举个例子

  • 笛卡尔积
SELECT * FROM t_dept, t_emp;

t_dept共20条记录,t_emp共6条记录。两表共同查询后共120条记录

  • 内连接
SELECT * FROM t_emp a INNER JOIN t_dept b ON  a.deptId = b.id;

只会把两个表共有的部分查询出来

  • 左外连接
SELECT * FROM t_emp a LEFT JOIN t_dept b ON  a.deptId = b.id;

取出左表的所有数据,然后有伴的数据满足就查询出来,不满足就填充null,和右外连接一致

  • 右外连接
SELECT * FROM t_emp a RIGHT JOIN t_dept b ON  a.deptId = b.id;
  • 左外连接取左表的独有部分
SELECT * FROM t_emp e LEFT JOIN t_dept d ON d.`id` = e.`deptId` WHERE d.id IS NULL
  • 右外连接取右表的独有部分
SELECT * FROM t_emp a RIGHT JOIN t_dept b ON a.deptId = b.id WHERE a.deptId IS NULL;

注意:判断字段是否为NULL时,不能使用’=’

因为 = NULL 的结果不会报错,但是结果永远为false。所以必须使用IS NULL来进行判空

  • 全外连接

MySQL不支持全外连接,要查询两个表的全集,需要合并两个查询结果,所以要使用 UNION 关键字

SELECT * FROM t_emp a LEFT JOIN t_dept b ON a.deptId = b.id
UNION
SELECT * FROM t_emp a RIGHT JOIN t_dept b ON a.deptId = b.id;

这种连接会把两个表有的都获取出来,然后对应的没有的置为null

  • 查询两表独有内容
SELECT * FROM t_emp a LEFT JOIN t_dept b ON a.deptId = b.id WHERE b.id IS NULL
UNION
SELECT * FROM t_emp a RIGHT JOIN t_dept b ON a.deptId = b.id WHERE a.deptId IS NULL;

子查询和分页查询

子查询

出现在其他语句内部的select语句,称为子 查询或内查询内部嵌套其他select语句的查询,称为外查询或主查询

例如:

select first_name from employees where department_id in(
    select department_id from departments where location_id=1700
)

特别注意:

  • 子查询要包含在括号内。
  • 将子查询放在比较条件的右侧。
  • 子查询 (内查询) 在主查询之前一次执行完成
  • 子查询的结果被主查询(外查询)使用 。

举个例子:谁的工资比 Abel 高?

SELECT last_name
FROM employees
WHERE salary > (SELECT salary FROM employees WHERE last_name = 'Abel');

会先执行完子查询,然后结果供主查询使用。

分页查询

当要查询的条目数太多,一页显示不全,这个时候就可以使用分页查询。

基本的语法格式:

select 查询列表
from 表
limit [offset,] size;
# 注意:
  offset代表的是起始的条目索引,默认从0开始
  size代表的是显示的条目数

一个固定的分页公式:

假如要显示的页数为page,每一页条目数为size:select 查询列表 from 表 limit (page-1)*size,size;

举个例子:

#案例1:查询前五条员工信息
SELECT * FROM  employees LIMIT 0,5;
SELECT * FROM  employees LIMIT 5;

#案例2:查询第11条——第25条
SELECT * FROM  employees LIMIT 10,15;

总结查询以及执行顺序

select 查询列表     7
from 表1 别名       1
连接类型 join 表2    2
on 连接条件          3
where 筛选          4
group by 分组列表    5
having 筛选         6
order by排序列表     8
limit 起始条目索引,条目数;  9

增删改

insert语句

基本语法格式:insert into 表名(字段名,...) values(值,...);

特别注意:

  • 要求值的类型和字段的类型要一致或兼容

  • 字段的个数和顺序不一定与原始表中的字段个数和顺序一致,但必须保证值和字段一一对应

  • 假如表中有可以为null的字段,注意可以通过以下两种方式插入null值

    • 字段和值都省略
    • 字段写上,值使用null
  • 字段和值的个数必须一致

  • 字段名可以省略,默认所有列

举个例子:

INSERT INTO departments(department_id, department_name,manager_id, location_id)
VALUES (70, 'Public Relations', 100, 1700);

如果有日期类型:字符和日期型数据应包含在单引号中。

INSERT INTO employees(employee_id,last_name,email,hire_date,job_id)
VALUES (300,’Tom’,’tom@126.com’,to_date(‘2012-3-21’,’yyyy-mm-dd’),’SA_RAP’);

一次插入多条语句的语法:insert into 表名【(字段名,..)】 values(值,..),(值,...)

举个例子:

INSERT INTO departments(department_id, department_name,manager_id, location_id)
VALUES 
(70, 'Public Relations', 100, 1700),
(71, 'Public sdf', 23, 65745),
(72, 'Public asdg', 54, 3454);

update语句

基本的语法格式:update 表名 set 字段=值,字段=值 【where 筛选条件】;

可以一次更新多条数据。如果需要回滚数据,需要保证在DML前,进行 设置:SET AUTOCOMMIT = FALSE;

使用 WHERE 子句指定需要更新的数据:

UPDATE employees SET department_id = 70 WHERE employee_id = 113;

如果省略 WHERE 子句,则表中的所有数据都将被更新:

UPDATE copy_emp SET department_id = 110;

delete语句

基本的语法格式:delete from 表名 【where 筛选条件】【limit 条目数】

使用 WHERE 子句删除指定的记录:delete from departments where department_name = 'Finance';

如果省略 WHERE 子句,则表中的全部数据将被删除:DELETE FROM copy_emp;

DDL语句

这个部分相对上面内容就少了很多了。

数据库的管理

创建数据库:create database [if not exists] 库名 [character set 字符集名];

修改库:alter database 库名 character set 字符集名;

删除库:drop database [if exists] 库名;

相关其他命令,这个一般用于命令行中:

  • show databases;查看当前所有数据库
  • use employees;“使用”一个数据库,使其作为当前数据库

表的管理语句

创建表:

create table 【if not exists】 表名(
	字段名 字段类型 【约束】,
	字段名 字段类型 【约束】,
	。。。
	字段名 字段类型 【约束】 
)
# 举个例子:
CREATE TABLE dept(
    deptno INT(2),
    dname VARCHAR(14),
    loc VARCHAR(13)
);

常用的数据类型:

INT 使用4个字节保存整数数据
CHAR(size) 定长字符数据。若未指定,默认为1个字符,最大长度255
VARCHAR(size) 可变长字符数据,根据字符串实际长度保存,必须指定长度
FLOAT(M,D) 单精度,M=整数位+小数位,D=小数位。 D<=M<=255,0<=D<=30, 默认M+D<=6
DOUBLE(M,D) 双精度。D<=M<=255,0<=D<=30,默认M+D<=15
DATE 日期型数据,格式’YYYY-MM-DD’
BLOB 二进制形式的长文本数据,最大可达4G
TEXT 长文本数据,最大可达4G

修改表的语句:

  • 添加列:alter table 表名 add column 列名 类型 [first|after 字段名];

  • 修改列的类型或约束:alter table 表名 modify column 列名 新类型 [新约束];

  • 修改列名:alter table 表名 change column 旧列名 新列名 类型;

  • 删除列:alter table 表名 drop column 列名;

  • 修改表名:alter table 表名 rename [to] 新表名;

  • 删除表:drop table [if exists] 表名;

建表的时候常见的约束

  • NOT NULL:非空,该字段的值必填
  • UNIQUE:唯一,该字段的值不可重复
  • DEFAULT:默认,该字段的值不用手动插入有默认值
  • CHECK:检查,mysql不支持
  • PRIMARY KEY:主键,该字段的值不可重复并且非空 unique+not null
  • FOREIGN KEY:外键,该字段的值引用了另外的表的字段

主键:一个表至多有一个主键,主键本生就包含了唯一和非空两个约束

外键的作用和注意点:

  • 用于限制两个表的关系,从表的字段值引用了主表的某字段值
  • 外键列和主表的被引用列要求类型一致,意义一样,名称无要求
  • 主表的被引用列要求是一个key(一般就是主键)
  • 插入数据,先插入主表
  • 删除数据,先删除从表
create table 表名(
	字段名 字段类型 not null,#非空
	字段名 字段类型 primary key,#主键
	字段名 字段类型 unique,#唯一
	字段名 字段类型 default 值,#默认
	constraint 约束名 foreign key(字段名) references 主表(被引用列)
)

在一张数据表建好之后,这些约束也可以通过SQL语句经行修改或者删除:

  • 添加非空:alter table 表名 modify column 字段名 字段类型 not null;
  • 删除非空:alter table 表名 modify column 字段名 字段类型 ;
  • 添加默认:alter table 表名 modify column 字段名 字段类型 default 值;
  • 删除默认:alter table 表名 modify column 字段名 字段类型 ;
  • 添加主键:alter table 表名 add [constraint 约束名] primary key(字段名);
  • 删除主键:alter table 表名 drop primary key;

更多的写法就自行搜索吧。

的字段值引用了主表的某字段值

  • 外键列和主表的被引用列要求类型一致,意义一样,名称无要求
  • 主表的被引用列要求是一个key(一般就是主键)
  • 插入数据,先插入主表
  • 删除数据,先删除从表
create table 表名(
	字段名 字段类型 not null,#非空
	字段名 字段类型 primary key,#主键
	字段名 字段类型 unique,#唯一
	字段名 字段类型 default 值,#默认
	constraint 约束名 foreign key(字段名) references 主表(被引用列)
)

在一张数据表建好之后,这些约束也可以通过SQL语句经行修改或者删除:

  • 添加非空:alter table 表名 modify column 字段名 字段类型 not null;
  • 删除非空:alter table 表名 modify column 字段名 字段类型 ;
  • 添加默认:alter table 表名 modify column 字段名 字段类型 default 值;
  • 删除默认:alter table 表名 modify column 字段名 字段类型 ;
  • 添加主键:alter table 表名 add [constraint 约束名] primary key(字段名);
  • 删除主键:alter table 表名 drop primary key;

更多的写法就自行搜索吧。


转载:https://blog.csdn.net/weixin_55086330/article/details/115028662
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场