MySQL01---MySQL基本语法

MySQL基本语法

一 数据类型

类型描述
int整型,和java中的int类型一样;
double浮点型,例如double(5,2)表示该列存放的数据最多是5位,而且其中必须有2位小数,它的最大值是:999.99;
decimal浮点型,用于保存对准确精度有重要要求的值,例如与金钱有关的数据。
char (120)固定长度字符串类型,如果没有指定长度,默认长度是255,如果存储的字符没有达到指定长度,mysql将会在其后面用空格补足到指定长度;
varchar(120)可变长度字符串类型,它的长度可以由我们自己指定,它能保存数据长度的最大值是65535,如果存储的字符没有达到指定的长度,不会补足到指定长度;
tinytext可变长度字符串类型,其存储范围是28-1B;
text也是可变长度字符串类型,其存储范围是216-1B;
mediumtext也是可变长度字符串类型,其存储范围是224-1B;
longtext也是可变长度字符串类型,其存储范围是232-1B;
tinyblob是可变长度二进制类型,其存储范围是28-1B;
blob是可变长度二进制类型,其存储范围是216-1B;
mediumblob也是可变长度二进制类型,其存储范围是224-1B;
longblob也是可变长度二进制类型,其存储范围是232-1B;
date日期类型,格式为yyyy-MM-dd,只有年月日,没有时分秒;
time时间类型,格式为hh:mm:ss,只有时分秒,没有年月日;
timestamp时间戳类型,格式为:yyyy-MM:dd hh:mm:ss,年月日,时分秒都有。

二 SQL语法详解

1.对数据库操作

# 创建数据库
# 使用默认的字符集与校对 
CREATE DATABASE 数据库名;
# 可以指定数据库字符
CREATE DATABASE 数据库名  CHARACTER SET gbk;
>CREATE DATABASE	:	创建 数据库
>CHARACTER SET		:	字符集  

# 查看当前服务器下所有数据库
SHOW DATABASES;

# 查看创建数据库的语句
SHOW CREATE DATABASE 数据库名;

# 删除数据库
DROP DATABASE 数据库名;

# 切换数据库
USE [DATABASE] 数据库名;

# 查看当前数据库
SELECT DATABASE();

2.对表进行操作

2.1 创建表

语法:

CREATE TABLE 表名(列名 类型,列名 类型, ... ,列名 类型);

2.2 查看表

# 查看表结构
DESC 表名;
desc person;

# 查看当前数据库下所有表
SHOW TABLES;

# 查看表的创建语句(包括字符编码集)
SHOW SHOW TABLE 表名;

2.3 修改表

基本不用 迫不得已也尽量别用,直接修改可能会导致一些不可预见的错误.

# 添加列操作 --- add
ALTER TABLE 表名 ADD 列名 类型;

# 修改列的类型 --- modify
ALTER TABLE 表名 MODIFY 列名 类型;

# 删除列 --- drop
ALTER TABLE 表名 DROP 列名;

# 修改列名称 --- change
ALTER TABLE 表名 CHANGE 旧列名 新列名 类型;

2.4 删除表(一般不用)

# 彻底删除 --- drop (直接删除文件)
DROP TABLE 表名;

# 删除记录 --- truncate (重置文件,清除内容及记录)
TRUNCATE TABLE 表名;

3.表中的约束

数据库中的约束,实际上就是表中数据的限制条件,在设计表的过程中,加入约束就是为了保证数据的有效性和记录的完整性.

  • 非空约束(not null)
  • 唯一性约束(unique)
  • 主键约束(primary key) PK
  • 外键约束(foreign key) FK

3.1 非空约束

  • 在建表的时候设置字段为 not null,这样在插入数据的时候这个字段必须赋值。
  • 如果在添加数据行的时候不为此字段赋值,报错.
  • 主要约束字符串类型,数字类型不写not null也不能为空
    演示:
CREATE TABLE 表名(列名 类型 NOT NULL,列名 类型, ... ,列名 类型);

3.2 唯一性约束

在建表时设置字段为unique,这个字段具有唯一性,不可重复,’'也不可重复,但是可以为null,null可以重复
如果输入重复字段,报错。

  • 列级约束
CREATE TABLE 表名(列名 类型 UNIQUE,列名 类型, ... ,列名 类型);
  • 表级约束
CREATE TABLE 表名(列名1 类型 ,
                列名2 类型, ... ,
                列名n 类型, 
                UNIQUE(列名1,列名2));
  • 表级约束可以给约束起一个别名方便以后删除
CREATE TABLE 表名(列名1 类型 ,
                列名2 类型, ... ,
                列名n 类型, 
                Constraint 约束1 UNIQUE(列名1,列名2));

Constraint是约束的关键字,约束的名字可以自取。

3.3 主键约束 — primary key

  • 一个表在设计的时候一定要有主键,每一行的主键是当前行的唯一标识。
  • 在给表中的某个字段添加主键约束后,这个字段成为主键字段,主键字段中的值成为主键值,这个字段不能为空也不能重复。
  • 在添加了主键之后,该字段不能为空也不能重复,和not null unique的效果是相同的,但是有本质上的区别,那就是主键约束出了上述效果外,还会默认添加索引—index
# 单一主键(列级定义)
CREATE TABLE Person(ID INT PRIMARY KEY ,name VARCHAR(255),age INT);

# 单一主键(表级定义)
CREATE TABLE Person(ID INT,name VARCHAR(255),age INT,CONSTRAINT [约束1] PRIMARY KEY(ID));

# 复合主键
CREATE TABLE Person(ID INT,name VARCHAR(255),age INT,CONSTRAINT [约束1] PRIMARY KEY(ID,name));

在MySQL中,提供了一个自增的数字来自动生成主键值,就是auto_increment,不需要我们自己维护,可以从1开始自动生成,按1递增,使用方法与约束相同。
注意:对于自动增长的列在添加列操作时,直接插入null值即可.


4.对表中数据操作

4.1 插入数据 — insert

以刚才创建的Person表为例:

  • 不指定列名 — 按照创建表时列的顺序,写出所有对应列的值
INSERT INTO Person VALUES (1,'郭德纲',50);
#也可以连续添加
INSERT INTO Person VALUES (1,'郭德纲2',50)(2,'于谦',51)(3,'高峰',55);

Snipaste_2020-10-24_21-23-14

  • 指定部分列 — 按照写入的列名添加值
INSERT INTO Person(age,name) VALUES (50,'郭德纲');

4.2 更新操作 — update

Update 语句用于修改表中的数据。

# 更新某一行中的一个列
UPDATE Person SET 列名x = 新值 WHERE 列名 = 某值;
UPDATE Person SET name = '郭德纲3' WHERE ID = 1;
#如果where指定的列的值指向了多个列,则所指向的列全部更改

# 更新某一行中的若干列
UPDATE Person SET name = '郭德纲3',age = 55  WHERE ID = 1;

4.3 删除操作 — delete

DELETE 语句用于删除表中的行。用于删除表中的数据

# 删除一行
DELETE FROM 表名称 WHERE 列名称 = 值

# 删除所有行
DELETE FROM table_name
或者
DELETE * FROM table_name

# 删除表中的所有数据 --- truncate
TRUNCATE TABLE 表名

4.4 基本查询操作

  • WHERE 子句用于规定选择的标准,规定查询条件查询范围
    基本语法演示:

Snipaste_2020-10-25_09-50-53

#查询符合要求的所有列
SELECT * FROM 表名 WHERE 列名x = xxx ;

#查询符合要求的指定列
SELECT 列名1,列名2...列名n FROM 表名 WHERE 列名x = xxx ;

#按范围查询 --- between ... and ...
SELECT * FROM 表名 WHERE BETWEEN 条件1 AND 条件2 ;

#以下操作以products表为例

#比较多个值 --- in 
# 例 查询出商品价格是65,100或190的商品信息
SELECT * FROM PRODUCTS WHERE PRICE IN(65,100,190);

#模糊查询 --- like (% 匹配多个(0-n)		_ 匹配一个(1))
# 例 查询出商品的名称中包含java的商品信息
SELECT * FROM PRODUCTS WHERE NAME LIKE '%JAVA%';

#null值操作 --- 判断是否为空 (is null;判断为空.	is not null;判断不为空)
# 例 查询出商品价格不为null商品信息
SELECT * FROM PRODUCTS WHERE PRICE IS NOT NULL;

#排序操作 --- order by (asc 升序 (默认) / desc 降序)
# 例 查询出所有商品,根据数量进行升序排列,如果数量相同,根据价格进行降序排列
SELECT * FROM PRODUCTS ORDER BY PNUM ASC,PRICE DESC;

4.5 聚合函数

  • Select简单的查询都是横向查询,它们都是根据条件一行一行的进行判断,而使用聚合函数查询是纵向查询,它是对一列的值进行计算,然后返回一个单一的值;另外聚合函数会忽略空值
    • count:统计指定列不为NULL的记录行数;
    • sum:计算指定列的数值和,如果指定列类型不是数值类型,那么计算结果为0;
    • max:计算指定列的最大值,如果指定列是字符串类型,那么使用字符串排序运算;
    • min:计算指定列的最小值,如果指定列是字符串类型,那么使用字符串排序运算;
    • avg:计算指定列的平均值,如果指定列类型不是数值类型,那么计算结果为0;
  • 语法演示:
# 统计价格大于50的记录数
SELECT COUNT(PRICE) FROM PRODUCTS WHERE PRICE >50;
# 统计商品总价值
SELECT SUM(PRICE*PNUM) FROM PRODUCTS;
# 统计price平均价格
SELECT AVG(PRICE) FROM PRODUCTS;
# 统计所有商品的平均价格
SELECT SUM(PRICE*PNUM) / SUM(PNUM) FROM PRODUCTS;
# 统计price最大(最小)值
SELECT MAX(PRICE) FROM PRODUCTS;

4.6 分组操作

  • GROUP BY 语句用于结合聚合函数,根据一个或多个列对结果集进行分组
  • 分组操作中的having子名是用于在分组后对数据进行过滤的,作用类似于where条件
  • 语法演示:
SELECT column_name, aggregate_function(column_name) FROM table_name WHERE column_name operator value GROUP BY column_name HAVING 条件
  • 例题演示
CREATE TABLE stu(id INT auto_increment PRIMARY key,name VARCHAR(255), gender VARCHAR(255),hobby varchar(255),math DOUBLE,chinese DOUBLE);

INSERT INTO stu VALUES(7,'CC','F','足球',60,80);
INSERT INTO stu VALUES(8,'DD','M','羽毛球',66,90);
INSERT INTO stu VALUES(9,'EE','F','乒乓球',45,32);
INSERT INTO stu VALUES(10,'FF','M','篮球',65,83);
INSERT INTO stu VALUES(11,'GG','M','乒乓球',91,62);
INSERT INTO stu VALUES(12,'HH','F','羽毛球',40,86);
INSERT INTO stu VALUES(13,'II','F','足球',67,60);
INSERT INTO stu VALUES(14,'JJ','M','足球',65,99);
INSERT INTO stu VALUES(15,'KK','F','乒乓球',41,78);

# 按照性别分组获得男女生人数
SELECT gender '性别',COUNT(id) '数量' from stu GROUP BY gender;
# 按照爱好分组获得人数
SELECT hobby '爱好',count(id) '人数' from stu group by hobby ;
# 按照性别分组求语文的平均成绩
select gender '性别',AVG(chinese) '语文(平均)' from stu group by gender;
# 按照性别分组求语文的最大 最小成绩
select gender '性别',MAX(chinese) '最高(语文)' ,min(chinese) '最低(语文)' from stu GROUP BY gender;
# 按照爱好分组求数学的平均成绩
SELECT hobby ,avg(math) from stu GROUP BY hobby;
# 按照爱好分组求数学的最大 最小成绩
SELECT hobby ,max(math),min(math) from stu GROUP BY hobby;
# 按照性别分组 求语文成绩总和和数学成绩总和
select gender , sum(chinese),sum(math) from stu GROUP BY gender;

5.函数

  • 字符串函数
# 返回字符串 s 的字符数 --- CHARACTER_LENGTH(s)
获取爱好列的字符数
select *,CHARACTER_LENGTH(hobby) from stu;

# 字符串 s1,s2 等多个字符串合并为一个字符串 --- CONCAT(s1,s2...sn)	
# 同 CONCAT(s1,s2,...) 函数,但是每个字符串之间要加上 x,x 可以是分隔符 --- CONCAT_WS(x, s1,s2...sn)
将数学语文结合为一个字符串,用' --- '隔开
SELECT id,name,concat_ws(' --- ',math,chinese)'数学,语文' from stu;

# 函数可以将数字 x 进行格式化 "#,###.##", 将 x 保留到小数点后 n 位,最后一位四舍五入。 ---FORMAT(x,n)
按照爱好分组求数学的平均成绩,保留两位小数
select *,format(avg(math),2) from stu GROUP BY hobby;.
# 为何乒乓球 的数学平均成绩自动保留到个位.
  • 数字函数
# 返回 x 的绝对值 --- ABS(x)
SELECT *,ABS(math) from stu;

# 返回一个表达式的平均值,expression 是一个字段 --- AVG(expression)
select avg(chinese) from stu ;

# 返回字段 expression 中的最小值 --- MIN(expression)
# 返回字段 expression 中的最大值 --- MAX(expression)
select max(math) from stu;
  • 日期函数
# 计算起始日期 d 加上 n 天的日期 --- ADDDATE(d,n)
SELECT NOW();
SELECT adddate(now(),5);

# 返回当前日期 --- CURRENT_DATE()
# 返回当前时间 --- CURRENT_TIME
# 返回当前日期和时间 --- CURRENT_TIMESTAMP()
select CURRENT_DATE();
select current_time;
select CURRENT_TIMESTAMP;

# 计算日期 d1->d2 之间相隔的天数 --- DATEDIFF(d1,d2)
select datediff('2020.8.6','2020-2-4');		#输入点.杠等符号都可识别
select datediff('2012.2.29',current_date);	#输入无效日期返回null

# 从日期或日期时间表达式中提取日期值 --- DATE()
SELECT date('2020.08.06 12.22.26');
select time('2020.08.06 12:22-26');		#使用点.杠.冒号等符号都可识别

# 按表达式 f的要求显示日期 d --- DATE_FORMAT(d,f)
select DATE_FORMAT(now(),'%Y-%m-%d %H-%i-%S')

# 函数从日期减去指定的时间间隔 --- DATE_SUB(date,INTERVAL expr type)
# 更为详细的adddate,可进行多种操作
select date_sub(now(),interval 2 day);
  • 其他函数
# 转换数据类型 --- CAST(x AS type)
select name,cast(math as signed) from stu ;

# 返回参数中的第一个非空表达式(从左向右)COALESCE(expr1, expr2, ...., expr_n)
select *,coalesce(chinese,math) from stu ;

# 如果 v1 的值不为 NULL,则返回 v1,否则返回 v2 --- IFNULL(v1,v2)
select ifnull(gender,'no') from stu;

# 如果表达式 expr 成立,返回结果 v1;否则,返回结果 v2 --- IF(expr,v1,v2)
select if(gender is null,'yes','no') from stu ;

6.多表数据关联操作

6.1 交叉连接

  • 实现原理为笛卡尔积
  • 语法
Select * from A cross join B;
Select * from A,B;

交叉连接---笛卡尔积

6.2 内连接

  • 内连接就是两张表同时都满足一定的条件的的结果
  • 内连接的结果为两表都包含的行
  • 语法:
# 显式内连接语法:
Select * from A inner join B on (连接条件[外键字段名=另一个表的主键字段])
select * from emp inner join dept on emp.deptno = dept.deptno;
(表格内容见下方综合练习)

# 隐式内连接语法:
Select * from A,B  where 条件
select * from orders A ,customer B where A.customer_id=B.id;

6.3 外连接

  • distinct 关键字(去重):放在打印信息前,去除打印内容里的重复信息。
# 左外连接 --- 以左边表为主
Select [DISTINCT] * from A left join B on (A.	外键字段=B.主键字段)

# 右外连接 --- 以右边表为主
Select * from A right join B on (连接条件)

左外连接

6.4 联合查询

  • UNION 操作符用于合并两个或多个 SELECT 语句的结果集。
  • 请注意,UNION 内部的 SELECT 语句必须拥有相同数量的列。列也必须拥有相似的数据类型。同时,每条 SELECT 语句中的列的顺序必须相同。
  • 单独使用union会去重,如果要全部数据使用union all。
  • 语法:
Select 字段  from A  where 条件
		Union
Select 字段 from  B  where 条件

6.5 子查询

  • 放在外面的查询语句称为父查询,放在里面查询称为子查询。
  • 语法
Select * from A  where Id in (Select id from B where 条件);

Select * from orders where customer_id=(select id from customer where name='zhangsan');

7.综合练习

7.1 题目

部门表	
CREATE TABLE DEPT(
	DEPTNO INT PRIMARY KEY,  -- 部门编号
    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');

员工表
CREATE TABLE EMP
    (
	EMPNO INT  PRIMARY KEY,  -- 员工编号
    ENAME VARCHAR(10),  -- 员工名称
    JOB VARCHAR(9), -- 工作
    MGR DOUBLE, -- 直属领导编号
    HIREDATE DATE,  -- 入职时间
    SAL DOUBLE, -- 工资
    COMM DOUBLE, -- 奖金
    DEPTNO INT, -- 部门号
    FOREIGN KEY(DEPTNO) REFERENCES DEPT(DEPTNO));
    
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-07-13',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-07-13',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 SALGRADE
      ( GRADE INT,  -- 工资等级
    LOSAL DOUBLE, -- 最低工资
    HISAL DOUBLE ); -- 最高工资
	
INSERT INTO SALGRADE VALUES (1,700,1200);
INSERT INTO SALGRADE VALUES (2,1201,1400);
INSERT INTO SALGRADE VALUES (3,1401,2000);
INSERT INTO SALGRADE VALUES (4,2001,3000);
INSERT INTO SALGRADE VALUES (5,3001,9999);

7.2 单表内容练习

1、查找部门30中员工的详细信息。
select * from emp where deptno = 30;
2、找出从事clerk工作的员工的编号、姓名、部门号。
select empno,ename,deptno from emp where job = 'clerk';
3、检索出奖金多于基本工资的员工信息。
select * from emp where comm>sal;
4、检索出奖金多于基本工资60%的员工信息。
SELECT * from emp where comm>(sal*0.6);
5、找出10部门的经理、20部门的职员 的员工信息。
SELECT * from emp where (deptno = 10 and job = 'manager') or (deptno = 20 and job = 'clerk');
6、找出10部门的经理、20部门的职员 或者既不是经理也不是职员但是工资高于2000元的员工信息。
SELECT * from emp where (deptno = 10 and job = 'manager') or (deptno = 20 and job = 'clerk') or (job <>'manager' and job<>'clerk' and sal>2000);
7、找出获得奖金的员工的工作。
select * from emp where comm is not null and comm <>0;
8、找出奖金少于100或者没有获得奖金的员工的信息。
select * from emp where comm<100 or comm is null;
9、找出姓名以A、B、S开始的员工信息。
select * from emp where ename like 'A%' or ename like  'B%' or ename like 'C%';
10、找到名字长度为7个字符的员工信息。
select * from emp where CHARACTER_LENGTH(ename) = 7;
11、名字中不包含R字符的员工信息。
select * from emp where IF(ename like '%R%',FALSE,TRUE);
12、返回员工的详细信息并按姓名排序。
select * from emp ORDER BY ename;
13、返回员工的信息并按员工的工作年限降序排列。
select * from emp order by hiredate ASC;
14、返回员工的信息并按工作降序工资升序排列。
select * from emp order by job desc ,sal asc;
15、计算员工的日薪(按30天)。
select *,(sal/30)as rixin from emp;
16、找出姓名中包含A的员工信息。
select * from emp where ename like '%A%';

7.3 综合练习

1、返回拥有员工的部门名、部门号。(dept,emp)	
select emp.*,dept.dname from emp left join dept on emp.deptno=dept.deptno;
2、工资水平多于smith的员工信息。
select * from emp where sal > (select sal from emp where ename = 'smith');
3、返回员工和所属经理的姓名。(自连接)
select emp1.ename '员工',emp2.ename'经理' from emp emp1 INNER JOIN emp emp2 on emp1.mgr = emp2.empno;
4、返回   雇员的雇佣日期早于其领导雇佣日期的      员工及其领导姓名。(在日期类型可以直接比较)
select yname,lname from (
select emp1.ename yname,emp1.hiredate ydate,emp2.ename lname,emp2.hiredate ldate from emp emp1 left join emp emp2 on emp1.mgr = emp2.empno
) emp where datediff(ydate,ldate)<0;
5、返回员工姓名及其所在的部门名称。
select emp.ename,dept.dname from emp LEFT JOIN dept on emp.deptno = dept.deptno;
6、返回从事clerk工作的员工姓名和所在部门名称。
select emp.ename,dept.dname from emp LEFT JOIN dept on emp.deptno = dept.deptno where job = 'clerk';
7、返回部门号及其本部门的最低工资。
select deptno,min(sal+ifnull(comm,0)) '最低工资' from emp GROUP BY deptno;
8、返回销售部(sales)所有员工的姓名。
select ename,dname from (
select emp.*,dept.dname from emp LEFT JOIN dept on emp.deptno = dept.deptno
) emp where dname='sales';
9、返回工资多于平均工资的员工。
SELECT * from emp where (sal+IFNULL(comm,0))>(
select avg(sal+IFNULL(comm,0)) from emp);
10、返回与SCOTT从事相同工作的员工。
select * from emp where job =(
select job from emp where ename = 'scott');
11、返回与30部门员工工资水平相同的员工姓名与工资。
select ename,sal from (
select emp.*,salgrade.grade from emp left JOIN salgrade on emp.sal BETWEEN salgrade.losal and salgrade.hisal) emp where grade = 
(select grade from salgrade where (
select avg(sal) from emp GROUP BY deptno having deptno = 30) BETWEEN losal and hisal);
12、返回工资高于30部门所有员工工资水平的员工信息。
select ename,sal from (
select emp.*,salgrade.grade from emp left JOIN salgrade on emp.sal BETWEEN salgrade.losal and salgrade.hisal) emp where grade > 
(select grade from salgrade where (
select avg(sal) from emp GROUP BY deptno having deptno = 30) BETWEEN losal and hisal);
13、返回部门号、部门名、部门所在位置及其每个部门的员工总数。
select dept.*,emp.renshu from dept LEFT JOIN (
select deptno,count(empno) renshu from emp GROUP BY deptno) emp on dept.deptno = emp.deptno;
14、返回员工的姓名、所在部门名及其工资。
select emp.ename,dept.dname,(emp.sal+IFNULL(emp.comm,0)) gongzi from emp LEFT JOIN dept on emp.deptno = dept.deptno;
15、返回员工的详细信息。(包括部门名)
SELECT emp.*,dept.dname from emp left JOIN dept on emp.deptno = dept.deptno;
16、返回员工工作及其从事此工作的最低工资。
select job,min(sal+IFNULL(comm,0)) losal from emp GROUP BY job;
17、返回不同部门经理的最低工资。
select deptno,min(sal+IFNULL(comm,0)) losal from emp where job = 'manager' group by deptno;
18、计算出员工的年薪,并且以年薪排序。
select *,((sal+IFNULL(comm,0))*12) nianxin from emp order by nianxin;
19、返回工资处于第四级别的员工的姓名。
select emp.ename,salgrade.grade from emp left JOIN salgrade on emp.sal BETWEEN salgrade.losal and salgrade.hisal where grade = 4;
20、返回工资为二等级的职员名字、部门所在地、和二等级的最低工资和最高工资
SELECT emp.ename,dept.loc,emp.losal,emp.hisal from (
select emp.*,salgrade.* from emp left JOIN salgrade on emp.sal BETWEEN salgrade.losal and salgrade.hisal where grade = 2) emp
LEFT JOIN dept on emp.deptno = dept.deptno ;
21、返回工资为二等级的职员名字、部门所在地、二等级员工工资的最低工资和最高工资
select * from (
SELECT emp.ename,dept.loc from (
select emp.*,salgrade.* from emp left JOIN salgrade on emp.sal BETWEEN salgrade.losal and salgrade.hisal where grade = 2) emp
LEFT JOIN dept on emp.deptno = dept.deptno 
) emp1 cross join (
select min(sal+IFNULL(comm,0)) min,max(sal+IFNULL(comm,0)) max from (
select emp.*,salgrade.* from emp left JOIN salgrade on emp.sal BETWEEN salgrade.losal and salgrade.hisal where grade = 2) emp2
) minmax;

三 事务

1.事务的概念

数据库中的事务是指对数据库执行一批操作,这些操作最终要么全部执行成功,要么全部 

失败,不会存在部分成功的情况。

2.事务的几个特性

  • 原子性
    事务的整个操作就像原子操作一样,最终要么全部成功,要么全部失败,这个原子性是从最终结果来看的,从最终结果看这个过程是不可再分的。

  • 一致性
    一个事务必须使数据库从一个一致性状态转换到另一个一致性状态。
    所谓一致性,指的是数据处于一个有意义的状态,最常见的例子就是转账,如果从A账户转入B账户一笔钱,A账户减少的同时B账户必须增加相同钱数,这样我们称之为有意义的。从实际的业务逻辑来说,就是最终结果和程序员期望的结果是一致的,完全符合的。

  • 隔离性
    一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事物之间不行互相干扰。

  • 持久性
    一个事务一旦提交,他对数据库中数据的改变就是永久性的。当事务提交之后,数据会持久化到硬盘,修改是永久性的。


版权声明:本文为lb634774742原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。