赞
踩
(自B站尚硅谷视频以及明日科技《MySQL从入门到精通》)
计算机管理 —> 服务与应用程序 --> 服务 --> MySQL (启动)
或者在控制台中输入如下命令(以管理员权限运行)
net start mysql #(关闭服务为 net stop mysql)?
mysql -h主机名 -P端口号 -u用户名 -p密码
EXIT | QUIT
mysqladmin -uroot -p原密码 password d新密码
CREATE DATABASE 库名;
CREATE SCHEMA 库名;
CREATE DATABASE 库名
CHARACTER SET = GBK;
CREATE DATABASE IF NOT EXISTS 库名;
SHOW DATABASES; #查看所有数据库
SELECT DATABASE;#查看当前所在库
SHOW TABLES;#查看当前库的所有表
SHOW TABLES FROM 库名;#查看其他库的所有表
DESC 表名;#查看当前库的单表结构
use 库名;
ALTER {DATABASE | SCHEMA} [库名]
[DEFAULT] CHARACTER SET [=] 字符集
| [DEFAULT] COLLATER [=] 校对规则名称
参数 | 说明 |
---|---|
{DATABASES| SCHEMAS} | 表示有一个必选项,这两个任选一个,皆可。 |
[数据库名] | 可选项,若无则修改当前(默认)的数据库 |
DEFAULT | 可选项,表示指定默认值 |
CHARACTER SET [=] 字符集 | 可选项,用于指定字符集,若无则使用MySQL默认的字符集 |
COLLATE [=] 校对规则名称 | 可选项,指定校对规则,如,utf8_bin,gbk_chinese_ci |
ps:使用ALTER [DATABASES|SCHEMA] 时,用户需要有管理员权限。
DROP DATABASE 库名;
CREATE [TEMPORARY] TABLE [IF NOT EXISTS] 数据表名
[create_definition,...][table_options][select_statement];
关键字 | 说明 |
---|---|
TEMPOARY | 如果使用该关键字,表示创建一个临时表 |
IF NOT EXISTS | 该关键字用于避免表存在时MySQL报告的错误 |
create_definition | 字段参数列表 |
table_options | 表的一些特性参数 |
select_statement | SELECT语句描述部分,用它可以快速建表 |
字段参数列表中,每一列具体定义如下:
字段名 type[NOT NULL|NULL] [DEFAULT default_value] [AUTO_INCREMENT]
[PRIMARY KEY][reference_definition]
参数(部分) | 说明 |
---|---|
type | 字段类型 |
NOT NULL | 是否允许为空,系统默认允许 |
DEFAULT default_value | 默认值 |
AUTO_INCREMENT | 是否自动编号,每个表中只能有一个AUTO_INCREMEN列,且必须被索引 |
PRIMARY KEY | 表示是否为主键,一个表中只能有一个。若没有,而某些应用程序需要主键,则MySQL将返回第一个没有任何NULL列的UNIQUE键作为PRIMARY KEY |
reference_definition | 注释 |
ALTER TABLE 表名 CHANGE [column] 旧字段名 新字段名 新数据类型;
存储引擎
字符集
自增类型字段初始值
DROP TABLE IF EXISTS 数据表名;
(六大约束:详见DDL语言学习中的常见约束)
insert into table_name(id,name) values(1,‘rose’); //添加
update table_name set name='lilei ’ where id=1; //修改
SELECT DISTINCT department _id FROM employee;//查询,可用逗号分隔开来多个字段
concat(st1,str2,…) as name FROM database;
起别名:AS
去重 :DISTINCT(搭配单个字符使用)
SELECT department_id FROM employee;(含有重复)
SELECT DISTINCT department_id FROM employee;(不含有重复)
连接 CONCAT
SELECT CONCAT(‘A’,“B”,“C”) AS 结果;
判断非空:IFNULL
SELECT IFNULL(commission_pct,0)
条件查询 WHERE
SELECT … FROM … WHERE …;
简单条件运算符: > < = != <> >= <=
逻辑运算符: && || !and or not (连接条件表达式)
模糊查询: (like) (between and) (IN) (is null) (NOT LIKE也阔以)
SELECT
last_name,
salary,
commission_pct
FROM
employees
WHERE
salary>=10000 AND salary<=20000
# salary BETWEEN 10000 AND 20000 不可颠倒顺序,左侧必为小,右侧必为大。
SELECT
*
FROM
employees
WHERE
last_name LIKE '%a%';// “%”是通配符,寻找名字包含a的名字
通配符:
_ : 任意单个字符
任意转义 ESCAPE ‘$’
排序查询:ORDER BY
SELECT 查询列表
FROM 表
[WHERE 筛选条件]
ORDER BY 排序列表 [ASC|DESC];
概念:MySQL中的数据用各种不同的技术存储在文件(或者内存)中。这些技术中的每一种技术都使用不同的存储机制、索引技巧、锁定水平并且最终提供广泛的不同的功能和能力。通过选择不同的技术,你能够获得额外的速度或者功能,从而改善你的应用的整体功能。这些不同的技术以及配套的相关功能在 MySQL中被称作存储引擎(也称作表类型)。
对比:Oracle 和SQL Server 等数据库只有一种存储引擎,而MySQL数据库提供了多种存储引擎。
查询:
# 查询(支持的)全部存储引擎(9个) //真的是支持的吗?support类型可见
SHOW ENGINES;
SHOW ENGINES\g
SHOW ENGINES\G // \G 可让结果更美观 (下图)
(当前版本: 8.0.23版本)
#查询当前MySQL服务器默认的存储引擎
SHOW VARIABLES LIKE 'storage_engine%'; //8.0.23版本查询之后没结果 可能是老版的吧
SHOW VARIABLES LIKE '%storage_engine%'; //查询之后有结果
太难了,还是看别人博客吧 (点击左侧链接打开博客)
数据类型(整数) | 取值范围(有符号值) | 取值范围(无符号值) | 说明 | 单位 |
---|---|---|---|---|
TINYINT | -127 ~ 127 | 0 ~ 255 | 最小的整数 | 1字节 |
BIT | -127 ~ 127 | 0 ~ 255 | 最小的整数 | 1字节 |
BOOL | -127 ~ 127 | 0 ~ 255 | 最小的整数 | 1字节 |
SMALLINT | -32768 ~ 32767 | 0 ~ 65535 | 小型整数 | 2字节 |
MEDIUMINT | -8388608 ~ 8388607 | 0 ~ 16777215 (满足百万) | 中型整数 | 3字节 |
INT | -2147683648 ~ 2147683647 | 0 ~ 4294967295 (满足亿) | 标准整数 | 4字节 |
BIGINT | -9223372036854775808 ~ | 0 ~ 1844… (满足19位) | 大整数 | 8字节 |
数据类型(浮点数) | 取值范围 | 说明 | 单位 |
---|---|---|---|
FLOAT | +(-)3.402823466E+38 | 单精度浮点数 | 8或4字节 |
DOUBLE | +(-)1.7976931348623157E+308 | 双精度浮点数 | 8字节 |
DECIMAL | 可变 | 一般整数 | 自定义长度 |
数据类型(定点型) 两个都一样 | 字节 |
---|---|
DEC (M,D) | M+2 |
decimal | M+2 |
D 代表小数点后保留D位小数,四舍五入地保留
M代表整数+小数位数 ,
若DECIMAL (5,2) 插入 1523.4 定点数会报错
默认精度(10,0)
定点型的精确度较高,如果要求插入的数据精度较高可以使用。
原则:所选择的类型越简单越好,能保存数值的类型越小越好。
类型 | 取值范围 | 说明 |
---|---|---|
[national] char (M) [binary|ASCII|unicode] | 0 ~ 255 个字符 | 固定长度为M(效率高) |
[national] varchar (M) [binary] | 0 ~ 255 个字符 | 长度可变,其余同char(M) (省空间) |
参数 | 说明 |
---|---|
national | 指定应该使用的默认字符集 |
binary | 指定数据是否区分大小写 |
ASCII | 指定使用latin1字符集 |
unicode | 指定使用UCS字符集 |
从小到大依次为: TINYTEXT (8次方), TEXT(16次方) , MEDIUMTEXT (24次方), LONGTEXT(32次方) 。 (BLOB 类似)
类型 | 最大值 | 说明 |
---|---|---|
Enum(“value1”,“value2”,…) | 65535 | 容纳所列值之一或者NULL |
Set(“value1”,“value2”,…) | 64 | 可以容纳一组值或者NULL |
ENUM 枚举 ‘a’ 时 , 若插入 其他的字符,则显示空,若插入 ‘A’,则显示’a’.
SET 当作一个集合 ,插入时
INSERT INTO TABLE tab_set VALUES('a,b,c');
类型 | 取值范围(最小) | 取值范围(最大) | 说明 | 字节 |
---|---|---|---|---|
DATE | 1000-01-01 | 9999-12-31 | 格式:YYYY-MM-DD | 4 |
TIME | -838:58:59 | 835:59:59 | 格式:HH:MM:SS | 3 |
DATETIME | 1000-01-01 00:00:00 | 9999-12-31 23:59:59 | 格式同理 | 8 |
TIMESTAMP | 1970-01-01 00:00:00 | 2037年某个时间 | 显示使用格式取决于M值 | 4 |
YEAR | 1901 | 2155 | 年份可指定两位数或者四位数 | 1 |
ps:
MySQL中,日期顺序按照 标准的ANSISQL格式进行输出。
timestamp(时间戳)跟实际的时区有关,且与当前的MySQL有关。
展示时区:SHOW VARIABLES LIKE ‘time_zone’;
SET time_zone = ‘+9:00’;
CREATE TABLE tab_int(
t1 INT # 有符号
t2 INT UNSIGNED # 无符号
);
老版本 插入超出范围的值 , 插入的是临界值
8.0 版本 直接报错
默认的长度是7 INT(7) 代表int类型默认的宽度
INT(7) ZEROFILL 用0填充直到宽度。
最常用的语法格式:
INSERT [LOW_PRIORITY|DELAYED|HIGH_PRIORITY][IGNORE]
[INTO] 数据表名 [(字段名,...)]
VALUES({值|DEFAULT},...),(...),...
[ON DUPLICATE KEY UPDATE 字段名 = 表达式,...]
参数说明如下:
参数 | 说明 |
---|---|
[LOW_PRIORITY|DELAYED|HIGH_PRIORITY] | 优先级参数 |
[IGNORE] | 出现的错误当作警告处理 |
[INTO] 数据表名 | 指定被操作的数据表 |
[(字段名,…)] | 不指定则默认所有列插入数据,否则表示向数据表的指定列插入数据 |
VALUES({值|DEFAULT},…),(…),… | 指定插入的数据值以及明确指定的默认值 |
[ON DUPLICATE KEY UPDATE 字段名 = 表达式,…] | 插入行时,如果导致UNIQUE KEY 或者PRIMARY KEY出现重复值,则根据UPDATE后面的语句修改原有数据 |
使用INSERT … VALUES 语句还可以一次性插入多条记录
INSERT INTO tb_manager(name,PWD)
VALUES ('admin','111'),
('hyy','111'),
('mingrisoft','111');
MySQL中,支持将查询的结果插入到指定的数据表中。
INSERT [LOW_PRIORITY|HIGH_PRIORITY][IGNORE]
[INTO] 数据表名 [(字段名,...)]
SELECT ...
[ON DUPLICATE KEY UNIQUE 字段名 = 表达式]
需要注意的是:SELECT 子句返回的结果集中的字段数,字段类型必须与目标数据表完全一致。
REPLACE INTO 表名 [(字段列表)] VALUES (值列表);
#或者使用SELECT语句 替换 VALUES 部分
UPDATE 数据表名 SET column_name = new_value1 ,....WHERE 条件表达式;
#更新时要保证WHERE子句正确性,否则破坏所有改变的数据
DELETE FROM 数据表名 WHERE 条件;
删除所有的行不必使用DELETE 语句
TRUNCATE [TABLE]数据表名;
对比:
SELECT [ALL | DISTINCT] 查询列表
FROM 表1
[INNER | NATURAL | LEFT | RIGHT ] JOIN 表2 ON 连接条件
WHERE 筛选条件
GROUP BY 分组字段 HAVING 分组后的筛选
ORDER BY 排序的字段 [DESC | ASC]
LIMIT offset,size; # 要显示条目的起始索引,从0开始和条目个数。
SELECT 分组函数,列(要求出现在GROUP BY的后面)
FROM 表
[WHERE 筛选条件]
GROUP BY 分组的列表
[HAVING 分组后的筛选]
[ORDER BY 子句]
注意:
查询列表比较特殊,要求是分组函数和GROUP BY后出现的字段。
特点:
分组查询中的筛选条件分为两类
关键字 | 数据源 | 位置 | |
---|---|---|---|
分组前筛选 | WHERE | 原始表 | GROUP BY 子句的前面 |
分组后筛选 | HAVING | 分组后的结果集 | GROUP BY子句的后面 |
①分组函数做条件肯定是放在HAVING子句中。
②能用分组前筛选的,就优先考虑分组前筛选(性能问题)。
分组函数
功能:用作统计使用,又称为聚合函数或统计函数或组函数
SUM,AVG 一般处理数值型
MAX,MIN,COUNT 可以处理任何类型
SUM(字符型) 结果为0 SUM (日期类型) 结果不行
分组函数都可以忽略NULL值。包括个数。比如AVG()十行非空 除 十行
可以和 DISTINCT 搭配,满足去重运算。
count函数的详细介绍(4种重载)
和分组函数一同查询的字段有限制
含义:又称多表查询,当查询的字段来自于多个表时,就会用到连接查询
笛卡尔乘积现象:表1:m行,表2:n行,结果=m*n行
发生原因:没有有效的连接条件
如何避免:添加有效的连接条件
按年代分
=
{
s
q
l
92
标准
:
仅仅支持内连接
s
q
l
99
标准
【推荐】:
支持内连接
+
外连接(左外和右外)
+
交叉连接
按年代分=\left\{
按功能分类
=
{
内连接
{
等值连接
非等值连接
自连接
外连接
{
左外连接
右外连接
全外连接
交叉连接
按功能分类=\left\{
最普遍最匀称的,包括相等连接和自然连接。使用等号运算符根据每个表共有的列的值匹配。
结果集只包含参加连接的表中与指定字段相符的行。
使用OUTER JOIN关键字将两个表连接起来
结果集不仅包含符合连接条件的行数据,还包括左表(左外连接),右表(右外连接)或两边连接表(全外连接)的所有数据行。
语法格式如下:
SELECT 字段名称 FROM 表名1 LEFT|RIGHT JOIN 表名2 ON 表名1.字段名1=表名2.属性名2;
等值连接 (=)
①多表等值连接的结果为多表的交集部分
②n表连接,至少需要n-1个连接条件
③多表的顺序没有要求
④一般需要为表起别名
⑤可以搭配前面介绍的所有子句使用,比如排序,分组,筛选
非等值连接(BETWEEN …AND …)
自连接
自己和自己连接
也支持一部分外连接(用于oracle,sqlserver。MySQL 不支持)
语法:
SELECT 查询列表
FROM 表1 别名
[连接类型] JION 表2 别名 ON 连接条件 //此处格式可重复多次(如果有三个及以上的表)
[WHERE 筛选条件]
[GROUP BY 分组]
[HAVING 筛选条件]
[ORDER BY 排序条件]
内连接特点:
外连接特点:LEFT| RIGHT | FULL OUTER JION
交叉连接特点:CROSS JION
功能: SQL99支持的较多
含义:出现在其他语句中的SELECT 语句,称为子查询或内查询
内部嵌套其他SELECT语句的查询,称为外查询或主查询。
分类:(B站尚硅谷分法)
相关操作符:比较运算符,IN,EXISTS,ANY,ALL。
操作符(多行比较操作符) | 含义 |
---|---|
IN | NOT IN | 等于列表中的任意一个 |
ANY | SOME | 和子查询返回的某一个值比较 |
ALL | 和子查询返回的所有值比较 |
可以放在
合并: 将多条查询语句的结果合并成一个结果集
应用场景: 要查询的结果来自于多个表,且多个表没有直接的关系,但要查询的信息一致。
语法:
查询语句1:
union
查询语句2
union
...
特点:
select 字段 as ‘xx’,
from 表 as ‘yy’
应用场景: 当要显示的数据,一页显示不全,需要分页提交sql请求
语法:
SELECT 查询列表
FROM 表
[JOIN TYPE JOIN 表2
ON 连接条件
WHERE 筛选条件
GROUP BY 分组字段
HAVING 分组后的筛选
ORDER BY 排序的字段]
LIMIT offset,size; // 要显示条目的起始索引,从0开始和条目个数。
特点:
要显示的页数 page , 每页的条目数 size
SELECT 查询列表
FROM 表
LIMIT (page-1)*size , size;
现有的存储引擎对子查询的优化没多表连接的那么好,所以能使用多表连接就尽量使用多表查询。
功能:类似于java 的方法,将一组逻辑语句封装在方法体内,对外暴露方法名。
好处:提高重用性和隐藏实现细节
调用: SELECT 函数名(实参列表);
round(x) x四舍五入
round(x,d) 小数点后保留d
ceil (x) 向上取整,返回>=该参数的最小整数
floor(x)向下取整,返回<=该参数的最大整数
truncate(x,d) 截断
SELECT TRUNCATE(1.6999,1) -> 1.6
mod(x,y) 取余 == % == a - a / b * b
rand 获取随机数,返回0-1之间的小数
now() 返回当前系统日期+时间
curdate() 返回当前系统日期
curtime() 返回当前时间
year(now()) 获取指定部分 // MONTH MONTHNAME
year(‘1998-1-1’)
year(hiredate) 年 FROM employees;
str_to_date(str,format) //转化格式
str_to_date(‘9-13-1999’,‘%m-%d-&Y’)
格式符 | 功能 |
---|---|
%Y | 四位的年份 |
%y | 2位的年份 |
%m | 月份(01,02…11,12) |
%c | 月份(1,2…11,12) |
%d | 日(01,02,…) |
%H | 小时(24小时制) |
%h | 小时(12小时制) |
%i | 分钟(00,01…59) |
%s | 秒(00,01…59) |
date_format(str,format) 格式日期
将日期转化成字符
SELECT DATE_FORMAT(NOW(),‘%y年%m月%d日’)AS out_put;、
DATEDIFF(date1,date2)//date1 - date2 返回两个日期相差的天数
VERSION(); //查看版本
DATABASE() //打开当前打开的库
USER() //当前用户
PASSWORD(‘字符’); //返回字符加密 – 已被弃用?
MD5(‘字符’) //返回字符的MD5的加密形式
IF ELSE
CASE
CASE 要判断的字段或者表达式
WHEN 常量1 then 显示的值为1
...
ELSE 要显示的值或语句
END
CASE
WHEN 条件1 THEN 要显示的值1或语句1
WHEN 条件2 THEN 要显示的值2或语句2
...
ELSE 要显示的值n或语句n
END
MySQL :select version();
控制台:mysql --version 或者 mysql -V
数据操作语言:
插入: insert 修改: update 删除: delete
语法1:
INSERT INTO 表名(列名,...) VALUES(值1,...);
语法2:
INSERT INTO 表名
SET 列名 = 值 , 列名 = 值 , ...
区别:
修改单表语法:
UPDATE 表名
SET 列 = 新值, 列 = 新值 , ...
WHERE 筛选条件;
修改多表语法:
#SQL92语法
UPDATE 表1 别名,表2 别名
SET 列 = 值,...
WHERE 连接条件
AND 筛选条件;
#99语法
UPDATE 表1 别名
INNER | LEFT | RIGHT JOIN 表2 别名
ON 连接条件
SET 列 = 值 ,...
WHERE 筛选条件;
单表:
DELETE FROM 表名 WHERE 筛选条件 [LIMIT 条目数];
多表:(sql 99)
DELETE 表1别名 , 表2别名
FROM 表1 别名
INNER| LEFT | RIGHT JOIN 表2 别名 ON 连接条件
WHERE 筛选条件;
不允许 + where
直接清空 表
CREATE DATABASE [IF NOT EXISTS ] 库名;
RENAME DATABASES 库名 TO 新库名; //废弃
ALTER DATABASE 库名 CHARACTER SET gbk;
DROP DATABASE [IF EXISTS] 库名;
create table 表名(
列名 列类型 【约束】。。。
);
ALTER TABLE book CHANGE COLUMN 列名1 列名2 类型;
ALTER TABLE book MODIFY COLUMN puhdate timestamp;
ALTER TABLE author ADD COLUMN annual DOUBLE ;
ALTER TABLE author DROP COLUMN annual;
ALTER TABLE author RENAME TO book_author;
DROP TABLE IF EXISTS book_author;
通用写法:
DROP DATABASE IF EXISTS old_database
CREATE DATABASE new_database;
DROP TABLE IF EXISTS old_table
CREATE TABLE new_table;
CREATE TABLE copy_table LIKE author;
CREATE TABLE copy2
SELECT * FROM author;
CREATE TABLE copy3
SELECT id,au_name
FROM author
WHERE 1=2; # 恒不成立 或者 0
含义:一种限制,用于限制表中的数据,为了保证表中数据的准确和可靠性。
分类:六大约束
NOT NULL: 非空,用于保证该字段的值不能为空
DEFAULT : 默认,用于保证该字段有默认值
PRIMARY KEY:主键,用于保证该字段的值具有唯一性,并且非空。
UNIQUE:唯一,用于保证该字段的值具有唯一性,可以为空。
CHECK:检查约束【MySQL不支持,好像8.0支持】
FOREIGN KEY:外键,用于限制两个表的关系,用于保证该字段的值必须来自于主表的关联列的值。
在从表添加外键约束,用于引用主表中的某列的值。
添加约束的时机:
约束的添加分类:
CREATE TABLE 表名(
字段名 字段类型 约束
字段名 字段类型
表级约束
)
保证唯一性 | 是否允许为空 | 数量 | |
---|---|---|---|
主键 | √ | × | 最多一个 |
唯一 | √ | √ | 可以多个 |
联合主键: PRIMARY KEY (id,stuname)
#语法:
references bookType(id)
#或者
FOREIGN KEY(btypeId) references bookType(id)
添加外键时在后面增加一个 ON DELETE CASCADE;
后面增加 ON DELETE NULL;
ALTER TABLE stuinfo MODIFY COLUMN stuname VARCHAR(20) NOT NULL;
ALTER TABLE stuinfo MODIFY COLUMN age INT DEFAULT 18;
ALTER TABLE stuinfo MODIFY COLUMN id INT PRIMARY KEY;
#列级约束
ALTER TABLE stuinfo ADD PRIMARY KEY(id);#表级约束
ALTER TABLE suinfo MODIFY COLUMN seat INT UNIQUE;
#列级约束
ALTER TABLE stuinfo ADD UNIQUE(seat);#表级约束
ALTER TABLE 表名 MODIFY COLUMN 列名 (啥都不写);
ALTER TABLE 表名 DROP PRIMARY KEY;
SHOW VARIABLE_NAME LIKE ‘%auto_increment%’;
通过 SET … = X; 来设置步长。
事务: 单独单元的一个或多个SQL语句组成,在这个单元中,每个MySQL语句是相互依赖的。
隐式事务:无明显的开启和结束标记
SELECT INSERT UPDATE DELETE …
显示事务:具有明显的开启和结束标记
前提先设置自动提交功能为禁用(每次都要手动设置。)
#开始事务
SET AUTOCOMMIT = 0 ;
SHOW VARIABLES LIKE '%AUTOCOMMIT%';
START TRANSACTION; #可选的
#结束事务
COMMIT ; #提交事务
ROLLBACK; #回滚事务
脏读:读取了更新但是没提交的数据,若回滚,则无效
不可重复读:两个事务重复读取了一个字段并作修改
幻读:T1读取字段后,T2对该表插入新行,T1再次读取则会多出新行。
事务隔离级别 | 脏读 | 幻读 | 不可重复读 |
---|---|---|---|
READ UNCOMMITTED | √ | √ | √ |
READ COMMITED | × | √ | √ |
REPEATABLE READ | × | × | √ |
SERIALIZABLE | × | × | × |
ps:MySQL中默认第三个隔离级别,Oracle中默认第二个隔离级别。 √ 代表出现该问题。
SELECT @@tx_isolation; (老版本?)
SELECT @@transaction_isolation; ( 8.0 )
SET SESSION TRANSACTION ISOLATION LEVEL + 隔离级别;
ps:需要每次连接都设置
SET autocommit = 0;
START TRANSACTION;
DELETE FOM account WHERE id = 25;
SAVEPOINT a; #设置保存点
DELETE FROM account WHERE id = 25;
ROLLBACK TO a; #回滚到保存点
MySQL中只保存数据逻辑,不保存数据。
# 创建视图 CREATE VIEW v1 # CREATE 可换成 ALTER AS SELECT stuname,majorname FROM stuinfo s INNER JOIN major m ON s.'majorid' = m.'id'; #使用视图查找姓张的学生和专业 SELECT * FROM v1 WHERE stuname LIKE '张%'; #删除视图 DROP VIEW 视图名,...; #查看视图 DESC 视图名; SHOW CREATE VIEW 视图名; #视图的更新 CREATE OR REPLACE VIEW 视图名 AS SELECT ... FROM ... #1插入 INSERT INTO 视图名 VALUES('张飞','...'); #2修改 UPDATE 视图名 SET 列名 = '...' WHERE ...; #3删除 DELETE FROM 视图名 WHERE 列名 = '...';
error: The target table … of the UPDATE is not updatable
包含以下关键字的SQL语句:
分组函数,distinct,group by, having,union 或union all
SELECT 中包含子查询
SELECT (SELECT MAX(salary) FROM employees) 最高工资;
常量查询
join(可以更新,但是不能插入,删除)
from一个不能更新的视图(套娃?)
where子句的子查询引用了from子句中的表
CREATE OR REPLACE VIEW ...
AS
SELECT ...
FROM 表1
WHERE ... IN(
SELECT ...
FROM 表1
WHERE ...
)
创建语法的关键字 | 是否实际占用物理空间 | 使用 | |
---|---|---|---|
视图 | CREATE VIEW | 只是保存了SQL逻辑 | 增删改查,一般不能 |
表 | CREATE TABLE | 保存了数据 | 增删改查 |
系统:全局+会话
自定义: 用户 + 局部
说明:变量由系统提供,不是用户定义,属于服务器层面使用的语法。
SHOW (SESSION | GLOBAL )VARIABLES;
# SESSION 是会话变量 GLOBAL 是全局变量
# 省略是会话变量
SHOW VARIABLES LIKE '%char%';
SELECT @@GLOBAL.系统变量名;#(GOLBAL改成SESSION就是会话变量)
赋值:(会话变量类似)
set global 系统变量名 = 值;
set @@global.系统变量名 = 值;
全局变量:作用域:服务器每次启动将为所有的全局变量赋初值,针对所有的会话(连接)有效,但不能跨重启。
会话变量:作用域:仅仅针对当前会话(连接)有效。
用户变量:
说明:变量是用户自定义的,不是系统的。
使用步骤 : 声明 + 赋值 + 使用(查看,比较,运算等等)
作用域 = 系统变量中的会话变量
SET @用户变量名 = 值;
SET @用户变量名:= 值;
SELECT @用户变量名:=值;
SELECT 字段 INTO 变量名 FROM 表;
SELECT @用户变量名;
局部变量
作用域:仅仅定义在它的begin end 中有效。
应用在 begin end 中的第一句话。
DECLARE 变量名 类型 (DEFAULT 值);
SET 局部变量名 = 值;
SET 局部变量名:= 值;
SELECT @局部变量名:=值;
含义: 类似于java中的方法
简直就是好嘛好处:
- 提高代码的重用性
- 简化操作
- 减少了编译次数,并且减少了和数据库服务器的连接次数,提高效率。
含义:一组预先编译好的SQL语句的集合,理解成批处理语句。
一.创建语法
DELIMITER $
CREATE PROCEDURE 存储过程名(参数列表)
BEGIN
存储过程体(一组合法的SQL语句)
END $
ps:
参数列表包含三部分:参数模式,参数名,参数类型
参数模式:
如果存储过程体只有一句话,BEGIN END 可以省略。
每条SQL语句结尾必须加分号
结尾可以使用DELIMITER重新设置
语法:DELIMITER 结束标记
二.调用方法
CALL 存储过程名(实参列表);
三.删除
drop procedure if exists test;
根据输入返回输出
CREATE PROCEDURE myp5(IN girlName VARCHAR(20), OUT boyName VARCHAR(20))
BEGIN
SELECT .. INTO boyName
FROM ..
INNER JOIN .. ON ..
WHERE ..
END ;
SET @bName; # 设置用户变量
CALL myp5('小昭',@bName);
语法:
CREATE FUNCTION 函数名(参数列表) RETURNS 返回类型
BEGIN
函数体
END
ps:
调用:SELECT 函数名(参数列表)
查看:SHOW CREATE FUNCTION 函数名;
删除:DROP FUNCTION 函数名;
存储过程的返回没限制,函数的返回只能是1个。
顺序结构:程序从上往下依次执行
分支结构:程序从两条或多条路径中选择一条去执行
循环结构:满足一定条件下,重复执行
IF (表达式1,表达式2,表达式3)
如果表达式1成立,则返回表达式2的值,否则返回表达式3的值。
#1 等值判断
CASE 变量|表达式|字段
WHEN 要判断的值 THEN 返回的值1
WHEN 要判断的值 THEN 返回的值2
...
ELSE 要返回的值
END CASE;
#2 区间判断
CASE
WHEN 条件1 THEN 返回的值1
WHEN 条件2 THEN 返回的值2
...
ELSE 返回值
END CASE ; # 如果返回的值是语句,则需要加分号
(可以作为表达式,嵌套使用)
IF 条件1 THEN 语句1;
ELSEIF 条件2 THEN 语句2;
...
[ELSE 语句n;]
END IF;
(while,loop,repeat)
循环控制:
iterate(结束本次循环,继续下次)
leave(结束循环)
[标签:] while 循环条件 do
循环体;
end while [标签] ;
[标签:] loop
循环体;
end loop [标签];
[标签:] repeat
循环体;
until 结束循环的条件
end repeat [标签];
information_schema
其中information_schema有62个表主要存储系统中的一些数据库对象信息,如用户表信息,列信息,权限信息,字符集信息,分区信息等等。
performance_schema
performance_schema有87个表,主要存储数据库服务器性能参数
mysql
mysql有31个表,主要存储系统用户的权限信息
不区分大小写,但建议关键字大写,表名,列名小写
每条命令最好用分号结尾 (还可以用 \g )
每条命令根据需要,可以缩进,或换行
注释
单行注释 : #注释文字
单行注释:-- 注释文字(注意有空格)
多行注释:/* 注释文字 */
数据库命名规则:
使用着重号 来表示这个是
字段`
SELECT
last_name,
department_id,
salary*12*(1+ IFNULL(commision_pct,0)) AS 年薪
FROM
employees
WHERE
id = 176;
SELECT *,salary*12*(1+IFNULL(commission_pct,0)) AS 年薪
FROM employees
ORDER BY salary*12*(1+IFNULL(commission_pct,0)) DESC;
#ORDER BY 年薪 DESC;
SELECT *
FROM employees
WHERE email LIKE "%e%"
ORDER BY LENGTH(email) DESC,department_id ASC;
SELECT salary 原始工资,department_id,
CASE department_id
WHEN 30 THEN salary*1.1
WHEN 40 THEN salary*1.2
WHEN 50 THEN salary*1.3
ELSE salary
END AS 新工资
FROM employees;
SELECT salary,
CASE
WHEN salary>20000 THEN 'A'
WHEN salary>15000 THEN 'B'
WHEN salary>10000 THEN 'C'
ELSE 'D'
END AS '工资级别'
FROM employees;
SELECT AVG(salary),department_id
FROM employees
GROUP BY department_id;
SELECT COUNT(*),department_id
FROM employees
GROUP BY department_id // 第一步
//WHERE COUNT(*)>2; //error:Invalid use of group function
HAVING COUNT(*)>2; //第二步
小结:WHERE 过滤行 , HAVING 过滤分组。
SELECT MIN(salary) 最低工资,manager_id 领导编号,salary
FROM employees
WHERE manager_id>102
GROUP BY manager_id
HAVING MIN(salary)>5000;
#GROUP BY 领导编号
#HAVING 最低工资>5000; //支持别名
SELECT last_name,department_name
FROM employees,departments
WHERE employees.department_id = departments.department_id;
# SQL92
SELECT last_name,department_name
FROM employees e,departments d //为表起别名
WHERE e.department_id = d.department_id;
#SQL 99
SELECT last_name,department_id
FROM departments d
INNER JOIN employees e
ON e.department_id = d.department_id;
SELECT salary,grade_level
FROM employees e,job_grades g
WHERE salary BETWEEN g.'lower_sal' AND g.'highest_sal';
SELECT e.employee_id,e.last_name,m.employee_id,m.last_name
FROM employees e,employees m
WHERE e.manager_id = m.employee_id;
SELECT department_name,COUNT(*) AS 员工个数
FROM departments d
INNER JOIN employees e
ON d.department_id = e.department_id
WHERE COUNT(*)>3
ORDER BY COUNT(*) DESC;
SELECT city,COUNT(*)
FROM locations l
LEFT OUTER JOIN departments d
ON l.location_id = d.location_id
WHERE d.department_id = NULL; //这是该表的主键。
#①查询job_id为‘IT_PROG’部门的所有工资
#②查询员工号,姓名以及salary, 其中 salary<①的任意一个
SELECT id,last_name,salary
FROM employees
WHERE salary < ANY (
SELECT salary
FROM employees
WHERE job_id = "IT_PROG"
) AND job_id <> 'IT_PROG';
#①查询job_id为‘IT_PROG’部门的最大工资
#②查询员工号,姓名以及salary, 其中 salary<①
SELECT id,last_name,salary
FROM employees
WHERE salary < (
SELECT MAX(salary)
FROM employees
WHERE job_id = "IT_PROG"
) AND job_id <> 'IT_PROG';
SELECT department_name
FROM departments d
WHERE EXISTS(
SELECT *
FROM employees e
WHERE d.department_id = e.department_id
);
SELECT * FROM employees LIMIT 10,15;
已知 表stuinfo
id | name | gradeId | sex | age | |
---|---|---|---|---|---|
学号 | 姓名 | 邮箱 john@126.com | 年级编号 | 性别 男/女 | 年龄 |
已知 表 grade
id | gradeName |
---|---|
年级编号 | 年级名称 |
一、查询所有学员的邮箱的用户名 (注:邮箱中@前面的字符)
SELECT substr(email,1,instr(email,'@') -1 )) 用户名
FROM stuinfo;
二、查询男生和女生的个数
SELECT SEX,COUNT(*) 个数
FROM stuinfo
GROUP BY sex;
三、查询年龄>18岁的所有学生的姓名和年级名称
SELECT name,gradeName
FROM stuinfo s
INNER JOIN grade g
ON s.gradeId = g.id
WHERE age > 18 ;
四、查询哪个年级的学生最小年龄>20岁
SELECT gradeId,MIN(age)
FROM stuinfo
GROUP BY gradeId
HAVING MIN(age) > 20 ;
五、试说出查询语句中涉及到的所有的关键字,以及执行先后顺序(DQL语言)
SELECT 查询列表 -----7
FROM 表 -----1
连接类型 JOIN 表2 -----2
ON 连接条件 -----3
WHERE 筛选条件 -----4
GROUP BY 分组列表 -----5
HAVING 分组后的筛选 -----6
ORDER BY 排序列表 -----8
LIMIT 偏移,条目数; ------9
SELECT d.* , ag
FROM departments d
JOIN(
SELECT AVG(salary) ag department_id
FROM employees
GROUP BY department_id
ORDER BY AVG(salary)
LIMIT 1
) ag_dep
ON d.department_id = ag_dep.department_id;
SELECT department_id,AVG(salary) 部门平均工资
FROM employees
GROUP BY department_id
HAVING 部门平均工资 > (
SELECT AVG(salary)
FROM employees e
);
CREATE TABLE stuinfo(
id INT PRIMARY KEY,
stuName VARCHAR(20) NOT NULL,
gender CHAR(1) CHECK(gender = '男' OR gender = '女'),
seat INT UNIQUE,
age INT DEFAULT 18,
majorId INT FOREIGN KEY REFERENCES major(id)
);
查看索引
SHOW INDEX FROM sutinfo;
CREATE TABLE stuinfo(
id INT ,
stuName VARCHAR(20),
gender CHAR(1) ,
seat INT ,
age INT ,
majorId INT
CONSTRAINT pk PRIMARY KEY (id),
...
CONSTRAINT fk_stuinfo_major FOREIGN KEY(majorid) REFERENCES major(id);
);#非空和默认不支持
DELIMITER $
CREATE PROCEDURE myinfo(IN bname VARCHAR(20))
BEGIN
SELECT b.*
FROM boys b
RIGHT JOIN information i ON b.id = i.id
WHERE b.name = bname;
END $
CALL myinfo('hyy') $
CREATE PROCEDURE myp3(IN username VARCHAR(20),IN PASSWORD VARCHAR(20))
BEGIN
#声明并初始化
DECLARE result VARCHAR(20) DEFAULT '';
#赋值
SELECT COUNT (*) INTO result
FROM admin
WHERE admin.username = username
AND admin.password = PASSWORD;
#使用
SELECT result;
END ;
CREATE FUNCTION myf3(deptName VARCHAR(20)) RETURNS DOUBLE
BEGIN
DECLARE sal DOUBLE ; # 声明局部变量
SELECT AVG(salary) INTO sal
FROM employees e
JOIN departments d ON e.department_id = d.department_id
WHERE d.department_name = deptName; # 赋值
RETURN sal; #返回结果
END $ #提前设置好结束符了
#调用
SELECT myf3('IT') $
CREATE PROCEDURE pro_while1(IN insertCount INT)
BEGIN
DECLARE i INT DEFAULT 1;
WHILE i<= insertCount DO
INSERT INTO admin(username,'password') VALUES(CONCAT('ROSE',i),'666')
SET i=i+1;
END WHILE;
END $
如果次数大于20则停止
CREATE PROCEDURE pro_while1(IN insertCount INT)
BEGIN
DECLARE i INT DEFAULT 1;
a: WHILE i<= insertCount DO
INSERT INTO admin(username,'password') VALUES(CONCAT('ROSE',i),'666')
IF i>=20 THEN LEAVE a;
END IF;
SET i=i+1;
END WHILE a;
END $
部分内容有所重复,见谅。
前部分笔记整理来自 明日科技《MySQL从入门到精通》,
后部分来自哔哩哔哩里
“MySQL_基础+高级篇- 数据库 -sql -mysql教程_mysql视频_mysql入门_尚硅谷”
CSDN博客 自测练习 附有建库命令 (较难)
SQL在线练习网站(简单)
[W3Cschool 理论练习](CSDN博客 自测练习 附有建库命令 ) (简单)
SQLBolt 学习 全英 (nice)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。