Mysql

Mysql安装步骤

点击next进行安装

1.png

用户自定义安装

1.png

在“Developer Components(开发者部分)”上左键单击,
选择“This feature, and all subfeatures, will be installed on local hard drive.”

1.png

点击change按钮 修改安装目录

1.png
1.png

这里是询问你是否要注册一个mysql.com的账号,或是使用已有的账号登陆mysql.com,一般不需要了,点选“Skip Sign-Up”,按“Next”略过此步骤

1.png

将 “Configure the Mysql Server now”前面的勾打上,点“Finish”结束软件的安装并启动mysql配置向导

1.png

选择安装模式

1.png
1.png
1.png
1.png

安装成功

1.png

使用Navicat操作Mysql数据库

1.gif

创建数据库
右键点击创建的数据库连接,选择新建数据库

1.gif

数据库名没有固定要求,字符集选择UTF-8

1.gif

使用SQL语句的方式

CREATE DATABASE  [IF NOT EXISTS] 数据库名

使用IF NOT EXISTS关键字,则当指定的数据库名存在时,不创建数据库。
如果不使用IF NOT EXISTS关键字,当创建的数据库名存在时,将产生错误。

创建表

create table 表明(
    列名 数据类型 [约束] [默认值],
    列名 数据类型 [约束] [默认值],
)

练习

创建学生表(Student) 学号-变长字符型(10),姓名-变长字符型(30)
性别-定长字符型(2),出生日期-日期类型

创建班级表(classes) ,班级编号-定长字符(4),班级名称-变长字符(30)

Mysql中常用的数据类型

  • 数据类型: 数字型: int,bigint
  • 变长字符串: varchar
  • 定长字符串:char
  • 小数型: float, double
  • 日期型: date(年月日)
  • datatime(年月日时分秒)

Mysql中的约束
对表中的数据加以限制,保证数据的安全性和严谨

  • 主键约束(primary key):主键约束相当于 唯一约束 + 非空约束 的组合,主键约束列中的数据不允许重复,也不允许出现空值,每个表最多只允许一个主键。

建表是在列上添加主键约束

create table temp( 
  id int primary key,
  name varchar(20)
);

建表后添加主键约束

alter table temp add primary key(id);
  • 非空约束(not null):非空约束用于确保当前列的值不为空值
    非空约束只能定义在列上
create table temp(
     id int primary key,
     name varchar(255) not null,
);
  • 唯一性约束(unique):该列中的数据不能有重复
 create table temp(
    id int primary key ,
    name varchar(20) not null,
    password varchar(10), unique(name,password)
);
  • 外键约束 (foreign key):外键约束是保两个表之间的参照完整性
--主表
create table temp(
id int primary key,
name varchar(20)
);

-- 副表
create table temp2(
id int,
name varchar(20),
classes_id int,foreign key(id) references temp(id)
);
插入数据
insert into  table_name [ (列名1,列2...) ] values(值1,值2,...)
  • 如果列名部分不写任何内容,表示默认对所有列插入数据
  • values中值的顺序必须与列对应相同
  • 插入字符和日期类型数据时,必须使用单引号括起来

练习:向学生表插入数据

1. s01 ,张三,男,1999-9-9

2. s02 ,李四,男,1997-5-9

3. s03 ,霸王龙,男,1989-4-7

4. s01 ,虞姬,女,1979-2-6

5. s01 ,花木兰,女
批量插入数据
INSERT INTO 表名[(字段列表)] VALUES
(值列表1),
(值列表2),
…
(值列表n);
修改数据
update 表名 set 列 = 修改后的值,[ 列 =修改后的值 ]
[ where 限制条件 ]
1.将修改张三的性别改为女

2.将学号s03学生的出生日期加两天

删除数据
delete [ from ] 表名 [where 限制条件]

练习

使用如下语句,创建学生表student和班级表class
create table student (        --学生表
            xh char(4),--学号
            xm varchar(10),--姓名
            sex char(2),--性别
            birthday date,--出生日期
            sal double(7,2), --奖学金
            studentcid int(2), --学生班级号
            foreign key(studentcid) references classes(classid)
)
Create table classes (   --班级表
            classid in(2), --班级编号
            cname varchar(20),--班级名称
            ccount  int(3) --班级人数
)
基于上述学生表和班级表,完成如下问题
(1)添加三个班级信息为:1,JAVA1班,null
                         2,JAVA2班,null
                         3,JAVA3班,null
(2)添加学生信息如下:‘A001’,‘张三’,‘男’,‘01-5月-05’,100,1
(3)添加学生信息如下:'A002','MIKE','男','1905-05-06',10
(4)插入部分学生信息: 'A003','JOHN','女’
(5)将A001学生性别修改为'女‘
(6)将A001学生信息修改如下:性别为男,生日设置为1980-04-01
(7)将生日为空的学生班级修改为Java3班
(8)请使用一条SQL语句,使用子查询,更新班级表中每个班级的人数字段

使用如下语句,建立以下表
CREATE TABLE copy_emp   (
  empno int(4),
  ename varchar(20),
  hiredate date,
  deptno int(2),
  sal double(8,2)
)

.在第三题表的基础上,完成下列问题
(1)在表copy_emp中插入数据,要求sal字段插入空值,部门号50,参加工作时间为2000年1月1日,其他字段随意
(2)在表copy_emp中插入数据,要求sal字段插入5000,部门号20,参加工作时间为2000年1月1日,姓名张三,编号1001
(3)修改copy_emp表中数据,要求10号部门所有员工涨20%的工资
(4)修改copy_emp表中sal为空的记录,工资修改为1000
(5)另外打开窗口2查看以上修改
(6)窗口1执行commit,窗口2中再次查看以上信息
(7)删除工资为空的员工信息
(8)执行rollback

TRUNCATE和DELETE区别

TRUNCATE是DDL,只能删除表中所有记录,释放存储空间,使用ROLLBACK不可以回滚。

DELETE是DML,可以删除指定记录,不释放存储空间,使用ROLLBACK可以回滚

事务

事务:也称工作单元,是由一个或多个SQL语句所组成的操作序列
这些SQL语句作为一个完整的工作单元,要么全都执行成功,要么全都执行失败。在数据库中,通过事务来保证数据的一致性。

事务的四个特性
  • 原子性:组成事务的DML操作语句要么全成功,要么全失败,不可能出现部分成功部分失败的情况。

  • 一致性:一旦事务完成,不管是成功的,还是失败,整个系统处于数据一致的状态

  • 隔离性:一个事务的执行不会被另一个事务所干扰

  • 持久性:事务一旦提交,对数据的改变就是永久的,不可以再被回滚

隐式提交:当下列任意一种情况发生时,会发生隐式提交

  • 执行一个DDL(CREATE、ALTER、DROP、TRUNCATE、RENAME)语句;

隐式回滚:当下列任意一种情况发生时,会发生隐式回滚

  • 客户端强行退出
  • 客户端连接到服务器端异常中断
  • 系统崩溃

MySQL默认是自动提交的,也就是你提交一个sql,就直接执行!
可以通过 set autocommit = 0 禁止自动提交
set autocommit = 1 开启自动提交 来实现事务的处理。
但要注意当用set autocommit = 0 的时候,以后所有的sql都将作为事务处理
直到用commit确认或 rollback结束

简单查询
CREATE TABLE `emp` (

`EMPNO` int(4) NOT NULL,

`ENAME` varchar(10) DEFAULT NULL,

`JOB` varchar(9) DEFAULT NULL,

`MGR` int(4) DEFAULT NULL,

`HIREDATE` date DEFAULT NULL,

`SAL` int(7) DEFAULT NULL,

`COMM` int(7) DEFAULT NULL,

`DEPTNO` int(2) DEFAULT NULL,

PRIMARY KEY (`EMPNO`),

KEY `FK_DEPTNO` (`DEPTNO`),

CONSTRAINT `FK_DEPTNO` FOREIGN KEY (`DEPTNO`) REFERENCES `dept` (`DEPTNO`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;


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-04-19', '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-05-23', '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 `dept` (

`DEPTNO` int(2) NOT NULL,

`DNAME` varchar(14) DEFAULT NULL,

`LOC` varchar(13) DEFAULT NULL,

PRIMARY KEY (`DEPTNO`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;



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');


查询所有列的数据

select * from 表名
select 列1,列2,列3... from 表名

查询指定列的数据

select 列1 [ ,列2] from  表名
运算符
+ , - ,* ,/

运算符的优先级

  • 乘除优先于加减
  • 相同优先权的表达式按照从左至右的顺序依次计算
  • 括弧可以提高优先权,并使表达式的描述更为清晰

空值(NULL)是指一种无效的、未赋值、未知的或不可用的值。
空值不同于零或者空格。

  • 任何包含空值的算术表达式运算后的结果都为空值NULL。
列别名 :用来对列重新命名,简化列名

列名的使用规则

方式1:列名 列别名
方式2:列名 AS 列别名

以下三种情况列别名两侧需要添加双引号

  • 列别名中包含有空格
  • 列别名中要求区分大小写
  • 列别名中包含有特殊字符

DISTINCT关键字消除重复数据

限制条件

--限制数据
--实际就是对检索的数据加上限制条件
--只有符合条件的数据才会显示在结果集中
--不符合条件的数据则不会显示
--语法 WHERE + 限制条件

-- select name ,身高
-- from emp
-- where 身高>180
--身高>180 逻辑表达式/条件表达式
-- 条件表达式 :> , < ,>=, <= ,<> != ,=

--查询部门号为10的员工姓名和薪资
select ename,sal,deptno
from emp
where deptno=10

SQL语句分析方式

-- 需要检索的列有哪些
-- 这些列来自于那张表
-- 是否存在限制条件

-- 查询薪资大于等于1500的员工编号和姓名以及薪资
-- 员工编号 姓名 薪资
-- EMP
-- 薪资大于等于1500
select empno ,ename ,sal
from emp
where sal>=1500;

特殊比较操作符
-- between 数值1 and 数值2
-- 表示某个列的值是否在数值1和数值2之间

select ename ,sal from emp where sal between 1500 and 3000;

--查询入职日期在81年2月22号之后入职的员工有哪些
-- 姓名/*
-- emp
-- 入职日期在81年2月22号之后 hiredate>81年2月22号
select * from emp
where hiredate>'02-4月-81'

--查询员工SMITH的薪资是多少
--检索薪资
--emp
--员工smith的薪资
select sal from emp
where ename='SMITH ';

--数值类型直接进行比较
--日期类型 需要写在单引号中 注意日期类型的数据书写格式 DD-MMM-YY
--字符类型 需要写在单引号中 区分大小写

--查询在81年2月20号 到 81年9月28号期间入职的员工有哪些
-- */ename
-- emp
-- between .. and
select ename ,hiredate
from emp
where hiredate between '20-2月-81' and '28-9月-81';

-- In()
-- 判断要比较的值是否于集合列表中的任意一个数据相同
--集合列表 表示括号中放入的值

select ename,deptno
from emp
where deptno in(10,30);

--查询薪资等于1500 或者等于3000的员工姓名和薪资
-- ename ,sal
--emp
-- sal=1500或者=3000
select ename,sal
from emp
where sal in(3000);

--is null 表示为空
判断要比较的值是不是为空
-- is not null 表示不为空

select ename ,comm 
from emp
where comm is null

select ename ,comm 
from emp
where comm is not null

--查询那些员工没有上级领导
select ename ,mgr
from emp
where mgr is null;

-- LIKE
-- 表示部分匹配
-- % 表示任意个字符 _ 表示一个字符

--查询员工姓名第一个字母是A的有哪些
select ename from emp
where ename like 'A%';

--查询员工姓名中第二个字母是A的有哪些
select ename from emp
where ename like '_A%';

逻辑比较符

-- and
-- 将多个条件表达式进行合并
-- 条件表达式1 and 条件表达式2
-- 只有1和2同时成立 整个结果才成立
-- 只要1和2当中有一个不成立 整个结果则不成立

select ename ,sal
from emp
where sal>=1500
and sal<=3000;

-- 查询部门号为10并且薪资大于1500的员工姓名,薪资,部门号
select ename,sal ,deptno
from emp
where deptno=10
and sal>1500;

--查询部门号为20,薪资大于800并且职位是SALESMAN
--的员工姓名,职位及薪资
select ename,sal,job
from emp
where deptno=30 AND sal>800 AND job='SALESMAN';

-- OR
-- 条件表达式1 OR 条件表达式2
-- 要求1或2中只要有一个成立 则整个结果成立

--查询薪资大于1500或者部门号为10的员工姓名和薪资以及部门
select ename ,sal ,deptno
from emp
where sal > 1500 or deptno=10;

--查询部门号不等于20的员工姓名
select ename from emp
where deptno<>20;

select ename from emp
where deptno!=20;

  • 逻辑运算符 AND 的优先级高于 OR
    -- 可以适用括号改变逻辑表达式的优先级
SELECT ename, job, sal
 FROM   emp
 WHERE  
( job='SALESMAN' OR  job='PRESIDENT') AND    sal>1500;

--排序 order by
-- ASC 表示升序 DESC 降序
--默认就是升序
select ename ,sal
from emp
order by sal desc;

排序规则(以升序为例)
数字升序排列小值在前,大值在后。即按照数字大小顺序由小到大排列。
日期升序排列相对较早的日期在前,较晚的日期在后。
字符升序排列按照字母由小到大的顺序排列。即由A-Z排列;中文升序按照字典顺序排列。
空值在升序排列中排在最前面,在降序排列中排在最后。

--多字段排序规则
先以第一个列进行排序 当第一个列中
出现重复记录时 再以后面列进行排序
order by 子句永远写在select语句的最后

使用select语句时,经常要返回前几条或者中间某几行记录,可以使用关键字limit。语法格式如下:
select 字段列表
from 数据源
limit [start,]length;
说明:
1.limit接受一个或两个整数参数。start表示从第几行记录开始输出,length表示输出的记录行数。
2.表中第一行记录的start值为0(不是 1)。

练习

1.使用两种方式查询所有员工(EMP)信息

2.查询(EMP)员工编号、员工姓名、员工职位、员工月薪、工作部门编号。

3.员工转正后,月薪上调20%,请查询出所有员工转正后的月薪。

4.员工试用期6个月,转正后月薪上调20%,请查询出所有员工工作第一年的年薪所得
(不考虑奖金部分,年薪的试用期6个月的月薪+转正后6个月的月薪)

5.查询员工表中一共有哪几种岗位类型。

6.查询职位为SALESMAN的员工编号、职位、入职日期。

7.查询1985年12月31日之前入职的员工姓名及入职日期。

8.查询部门编号不在10部门的员工姓名、部门编号。

9.查询入职日期在82年至85年的员工姓名,入职日期。

10.查询月薪在3000到5000的员工姓名,月薪。

11.查询部门编号为10或者20的员工姓名,部门编号。

12.查询经理编号为7902, 7566, 7788的员工姓名,经理编号。

13.查询员工姓名以W开头的员工姓名。

14.查询员工姓名倒数第2个字符为T的员工姓名。

15.查询奖金为空的员工姓名,奖金。

16.查询工资超过2000并且职位是MANAGER,或者职位是SALESMAN的员工姓名、职位、工资

17.查询工资超过2000并且职位是 MANAGER或SALESMAN的员工姓名、职位、工资。

18.查询部门在10或者20,并且工资在3000到5000之间的员工姓名、部门、工资。

19.查询入职日期在81年,并且职位不是SALES开头的员工姓名、入职日期、职位。

20.查询职位为SALESMAN或MANAGER,部门编号为10或者20,姓名包含A的员工姓名、职位、部门编号。

21.查询部门在20或30的员工姓名,部门编号,并按照工资升序排序。

22.查询工资在2000-3000之间,部门不在10号的员工姓名,部门编号,工资,
   并按照部门升序,工资降序排序。

23.查询入职日期在82年至83年之间,职位以SALES或者MAN开头的员工姓名,入职日期,职位,
   并按照入职日期降序排序。

24.查询入职时间在1982-7-9之后,并且不从事SALESMAN工作的员工姓名、入职时间、职位。

25.查询员工姓名的第三个字母是a的员工姓名。

26.查询除了10、20号部门以外的员工姓名、部门编号。

27.查询部门号为30号员工的信息,先按工资降序排序,再按姓名升序排序。
 
28.查询没有上级的员工(经理号为空)的员工姓名。

29.查询工资大于等于4500并且部门为10或者20的员工的姓名\工资、部门编号

30.查询入职日期最早的前5名员工姓名,入职日期。

Mysql 单行函数

数值函数

ABS(x):返回x的绝对值;

SQRT(x):返回非负数x的平方根;

PI():返回圆周率;

MOD(x,y)或%:返回x被y除的余数;

CEIL(x)、CEILING(x):返回大于或者等于x的最小整数值;

FLOOR(x):返回小于或者等于x的最大整数值;

ROUND(x,y):返回保留小数点后面y位,四舍五入的整数;

TRUNCATE(x,y):返回被舍弃的小数点后y位的数字x;

RAND():每次产生不同的随机数;

POW(x,y)和POWER(x,y): 返回x的y次乘方的结果值;

练习

1.写一个查询,分别计算100.456 四舍五入到小数点后第2位,第1位,整数位的值。

2.写一个查询,分别计算100.456 从小数点后第2位,第1位,整数位截断的值。

字符函数

CHAR_LENGTH(str):返回字符串str的所包含字符个数;

LENGTH(str):返回字符串str的长度;

CONCAT(s1,s2,...): 字符串连接;

CONCAT_WS(x,s1,s2,…):字符串连接, x是其它参数的分隔符;

INSERT(s1,x,len,s2) :返回字符串s1,s1中插入字符串s2;

LOWER (str)|LCASE (str):将字符串全部转换成小写字母;

UPPER(str)|UCASE(str):将字符串全部转换成大写字母;

LEFT(s,n):返回最左边指定长度的字符;

RIGHT(s,n):返回最右边指定长度的字符;

LPAD(s1,len,s2) | RPAD(s1,len,s2) :填充字符串函数;

TRIM(s1 FROM s)  |  LTRIM(s)|RTRIM(s):删除空格函数;

REPEAT(s,n):重复生成字符串函数;

SPACE(n):返回一个由n个空格组成的字符串;

REPLACE(s,s1,s2):字符串替换函数;

STRCMP(s1,s2):比较字符串大小函数;

SUBSTRING(s,n,len):获取子串函数;

LOCATE(str1,str) | POSITION(str1 IN str) | INSTR(str, str1):匹配子串开始位置函数;

REVERSE(s):将字符串s反转;

练习

1.显示所有员工姓名的前三个字符

2.显示正好为5个字符的员工的姓名,工资,部门号

3.写一个查询,用首字母大写,其它字母小写显示雇员的 ename,显示名字的长度,.
  并给每列一个适当的标签,条件是满足所有雇员名字的开始字母是J、A 或 M 的雇员,
  并对查询结果按雇员的ename升序排序。(提示:使用length、substr)

4.查询员工姓名中中包含大写或小写字母A的员工姓名。

5.显示所有员工的姓名,用a替换所有"A"

6.查询部门编号为10或20,入职日期在81年5月1日之后,并且姓名中包含大写字母A的员工姓名,员工姓名长度

7.查询每个职工的编号,姓名,工资要求将查询到的数据按照一定的格式合并成一个字符串.
前10位:编号,不足部分用*填充,左对齐
中间10位:姓名,不足部分用*填充,左对齐
后10位:工资,不足部分用*填充,右对齐

日期函数

CURDATE()和CURRENT_DATE() :获取当前日期函数;

NOW():返回服务器的当前日期和时间;

CURTIME():返回当前时间,只包含时分秒;

TIMEDIFF(expr1, expr2):返回两个日期相减相差的时间数;

DATEDIFF(expr1, expr2):返回两个日期相减相差的天数;

DATE_ADD(date,INTERVAL expr type):日期加上一个时间间隔值;

DATE_SUB(date,INTERVAL expr type):日期减去一个时间间隔值;

DATE(date)、TIME(date)、YEAR(date):选取日期时间的各个部分:

EXTRACT(unit  FROM  date):从日期中抽取出某个单独的部分或组合;

DAYOFWEEK(date) 、DAYOFMONTH(date) 、DAYOFYEAR(date):返回日期在一周、一月、一年中是第几天

DAYNAME、MONTHNAME:返回日期的星期和月份名称;

DATE_FORMAT(date,format):格式化日期;

TIME_FORMATE(time,formate):格式化时间;

type

YEAR ,MONTH,DAY ,HOUR,MINUTE,SECOND

格式码 format


%a  缩写星期名
%b  缩写月名
%c  月,数值
%D  带有英文前缀的月中的天
%d  月的天,数值(00-31)
%e  月的天,数值(0-31)
%f  微秒
%H  小时 (00-23)
%h  小时 (01-12)
%I  小时 (01-12)
%i  分钟,数值(00-59)
%j  年的天 (001-366)
%k  小时 (0-23)
%l  小时 (1-12)
%M  月名
%m  月,数值(00-12)
%p  AM 或 PM
%r  时间,12-小时(hh:mm:ss AM 或 PM)
%S  秒(00-59)
%s  秒(00-59)
%T  时间, 24-小时 (hh:mm:ss)
%U  周 (00-53) 星期日是一周的第一天
%u  周 (00-53) 星期一是一周的第一天
%V  周 (01-53) 星期日是一周的第一天,与 %X 使用
%v  周 (01-53) 星期一是一周的第一天,与 %x 使用
%W  星期名
%w  周的天 (0=星期日, 6=星期六)
%X  年,其中的星期日是周的第一天,4 位,与 %V 使用
%x  年,其中的星期一是周的第一天,4 位,与 %v 使用
%Y  年,4 位
%y  年,2 位

转换函数

if 函数:IF(expr1,expr2,expr3)
如果表达式1成立,返回结果是表达式2的值,否则返回表达式3的值
返回结果可以是数值,也可以是字符串

SELECT IF(1>2,1,2) from  dual; - - 2

SELECT IF(1<2,1,2) from  dual; - -1

IFNULL函数:IFNULL(n,m)
如果n的不为null则返回n的值,否则返回m的值

select IFNULL(1,2) FROM dual; - -1

select IFNULL(null,2) FROM dual - -2

练习

1.查询服务器当前时间

2.查询部门10,20的员工截止到2000年1月1日,工作了多少个月,入职的月份。

3.如果员工试用期6个月,查询职位不是MANAGER的员工姓名,入职日期,
  转正日期,入职日期是第多少月,第多少周

4.计算2000年1月1日到现在有多少月,多少周(四舍五入)。

5.查询员工ENAME的第三个字母是A的员工的信息(使用2个函数)。

6.使用trim函数将字符串‘hello’、‘  Hello ’、‘bllb’、‘ hello    ’
  分别处理得到下列字符串ello、Hello、ll、hello。

7.将员工工资按如下格式显示:123,234.00 RMB 。

8.查询员工的姓名及其经理编号,要求对于没有经理的显示“No Manager”字符串。

9.将员工的参加工作日期按如下格式显示:月份/年份

10.创建一个查询显示所有雇员的 ename和 sal。格式化sal为 15 个字符长度,用 $ 左填充,列标签 SALARY
CREATE TABLE SALGRADE( 
  GRADE int,
  LOSAL int,
  HISAL int
)ENGINE=InnoDB DEFAULT CHARSET=utf8;

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);
多表连接

在多个表之间通过一定的连接条件,使表之间发生关联,进而能从多个表之间获取数据

select table1.colum ,table2.colum  from  table1,table2

以上SQL已经实现了两个的连接,但是查询的结果集中会存在大量的重复数据

笛卡尔积:第一个表中的所有行和第二个表中的所有行都发生连接。

select table1.colum ,table2.colum  from  table1,table2
where 表之间的关联条件

等值连接

查询员工姓名,薪资,部门地点

查询员工编号,职位,工作地点,部门号,部门名称

使用and 添加其他限制条件

多表关联时,如何使用了两个表中相同名字的列,需要进行区分

通过表别名简化SQL

练习

1.写一个查询,显示所有员工姓名,部门编号,部门名称。

2.写一个查询,显示所有工作在CHICAGO并且奖金不为空的员工姓名,工作地点,奖金

3.写一个查询,显示所有姓名中含有A字符的员工姓名,工作地点。

非等值连接

查询每个员工的姓名,工资,工资等级

三个表关联查询

查询每个员工的编号,姓名,工资,工资等级,所在工作城市,按照工资等级进行升序排序

自连接,是一个表通过某种条件和本身进行连接的一种方式,就如同多个表连接一样

查询每个员工的姓名和直接上级姓名

查询所有工作在NEW YORK和CHICAGO的员工姓名,员工编号,以及他们的经理姓名,经理编号。

SQL99 标准关系型数据库语法

交叉连接会产生连个表的交叉乘积,和两个表之间的笛卡尔积是一样的;

SELECT  emp.empno,emp.ename,emp.sal,emp.deptno,dept.loc 
FROM    emp 
CROSS  JOIN dept; 
多表关联语法  
join :两边写需要进行关联的数据表
on  : 表的关联条件

SELECT  e.empno, e.ename, e.deptno, d.deptno, d.loc 
FROM    emp e   JOIN    dept d 
ON      (e.deptno = d.deptno); 
查询所有雇员姓名,部门编号,部门名称,包括没有部门的员工也要显示出来

左外连接 join关键字 左边的表为主表,主表中不满足关联条件的数据也查询出来

SELECT  e.empno, e.ename, e.deptno, d.deptno, d.loc 
FROM    emp e   LEFT   JOIN  dept d 
ON      (e.deptno = d.deptno); 

右外连接 join关键字 右边的表为主表,主表中不满足关联条件的数据也查询出来

SELECT  e.empno, e.ename, e.deptno, d.deptno, d.loc 
FROM    emp e   RIGHT JOIN  dept d 
ON      (e.deptno = d.deptno); 

练习

1.使用ON子句,显示工作在CHICAGO的员工姓名,部门名称,工作地点,薪资等级

2.使用左连接,查询每个员工的姓名,经理姓名,没有经理的King也要显示出来。

3.使用右连接,查询每个员工的姓名,经理姓名,没有经理的King也要显示出来。

4.显示员工SMITH的姓名,部门名称,直接上级名称

5.显示员工姓名,部门名称,工资,工资级别,要求工资级别大于4级。

6.显示员工KING和FORD管理的员工姓名及其经理姓名。

7.显示员工姓名,参加工作时间,经理名,参加工作时间,要求参加时间比经理早。

8.显示工作在CHICAGO的员工姓名,部门名称,工作地点

9.显示入职日期在81年2月1日之后的员工姓名,部门名称,入职日期

10.显示员工JONSE的部门名称,直接上级名称

11.列出受雇日期早于其直接上级的所有员工的编号,姓名,部门名称

12.查询所有工作在NEW YORK和CHICAGO的员工姓名,员工编号

13.查询所有工作在NEW YORK和CHICAGO的员工姓名,员工编号,以及他们的经理姓名,经理编号

14.显示所有工作在CHICAGO并且奖金不为空的员工姓名,工作地点,奖金

15.写一个查询,显示所有姓名中含有A字符的员工姓名,工作地点

16.查询部门人数在2人以上的部门名称、最低工资、最高工资,并对求得的工资进行
   四舍五入到整数位。

分组函数
--MAX() MIN() SUM() AVG() COUNT()

--MAX() 求一组数据的最大值
--MIN() 求一组数据的最小值
MIN和MAX可以用于任何数据类型

--SUM() 求一组数据的和
--AVG() 求一组数据的平均值
SUM和AVG函数都是只能够对数值类型的列或表达式操作

--COUNT() 统计数 / 记录数
除了COUNT(*)之外,其它所有分组函数都会忽略列中的空值,然后再进行计算

--查询emp表中的薪资的最大值和最小值

--求所有员工薪资和

--求所有员工平均薪资

--查询有多少部门

--查询20部门的最高薪资

--查询部门20的员工,每个月的工资总和及平均工资。

-- 查询工作在CHICAGO的员工人数,最高工资及最低工资。

-- 查询员工表中一共有几种岗位类型。

通过 GROUP BY 子句可将表中满足WHERE条件的记录按照指定的列划分成若干个小组

问题: 求各部门平均工资

在SELECT子句中的列除了分组函数那些项,所有列都必须包含在GROUP BY 子句中。


SELECT   ename,deptno, AVG(sal)
FROM     emp
GROUP BY deptno;

练习

1.查询每个部门每个岗位的工资总和

2.查询每个部门的部门编号,部门名称,部门人数,最高工资,最低工资,工资总和,平均工资。

3.查询每个部门,每个岗位的部门编号,部门名称,岗位名称,部门人数,最高工资,最低工资,工资总和,平均工资。

4.查询每个经理所管理的人数,经理编号,经理姓名,要求包括没有经理的人员信息

分组函数不能使用在WHERE子句中

SELECT   deptno, max(sal)
FROM     emp
WHERE    max(sal) > 2900
GROUP BY     deptno;

使用 having 子句

SELECT   deptno, max(sal)
FROM     emp
GROUP BY     deptno
having  max(sal) >2900

练习

1.查询每个部门最高工资大于2900的部门编号,最高工资

2.查询部门人数大于2的部门编号,部门名称,部门人数。

3.查询部门平均工资大于2000,且人数大于2的部门编号,部门名称,部门人数,
  部门平均工资,并按照部门人数升序排序

列出最低薪金大于1500的各种工作及此从事此工作的全部雇员人数

显示各种职位的最低工资

显示平均工资为>2000的职位

找每个部门的最高和最低的工资

找每个部门中每种职位的最高和最低的工资

显示出平均工资大于2000的部门名称及平均工资

显示每个部门每种工作平均工资大于2500的部门及工作

显示出工作名称中包含"MAN",并且平均工资大于1000的工作名称及平均工资

显示出平均工资最高的的部门平均工资
子查询

思考问题:查询比SMITH工资高的员工有哪些

子查询可以嵌于以下SQL子句中:

  • WHERE子句

查询比JONES入职晚的员工姓名以及入职日期

  • HAVING子句

查询部门最低工资比20部门最低工资高的部门编号及最低工资

  • FROM子句

查询员工工资为其部门最低工资的员工的编号和姓名及工资

子查询只返回一行一列 使用单行运算符
>, < ,>= ,<= ,= ,<>

练习

1.查询入职日期最早的员工姓名,入职日期

2.查询工资比SMITH工资高并且工作地点在CHICAGO的员工姓名,工资,部门名称

3.查询入职日期比20部门入职日期最早的员工还要早的员工姓名,入职日期

4.查询部门人数大于所有部门平均人数的的部门编号,部门名称,部门人数

5.显示工资比'ALLEN'高的所有员工的姓名和工资

6.显示与'SCOTT'从事相同工作的员工的详细信息

7.显示与30号部门'MARTIN'员工工资相同的员工的姓名和工资

8.查询所有工资高于平均工资(平均工资包括所有员工)的销售人员('SALESMAN')

9.显示每个部门名称和人数
什么是视图

视图是逻辑上来自一个或多个表的数据集合

为什么使用视图

限制其它用户对数据库表的访问,因为视图可以有选择性的显示数据库表的一部分;
容易实现复杂的查询;
对于相同的数据可以产生不同的视图;

创建视图
CREATE [OR REPLACE] VIEW view_name [(column_list)] 
AS select_statement

OR REPLACE:如果所创建的视图已经存在,该选项表示修改原视图的定义
view_name :视图的名称;
column_list :列名,列名的数量必须和视图所对应查询语句的列数量相等;
select_statement :一条完整的SELECT语句;

创建一个视图v_emp1,通过该视图只能查看10号部门的员工编号,员工姓名,职位。

  CREATE VIEW  v_emp1
  AS SELECT empno, ename, job
  FROM  emp
  WHERE deptno = 10;

练习

1.创建一个视图,通过该视图可以查询到工资在2000-5000内并且姓名中包含有A的员工编号,姓名,工资。

2.通过上述创建的视图查询数据

3.创建一个视图,通过该视图可以查询到工作在NEW YORK和CHICAGO的员工编号,姓名,部门编号,入职日期。

4.创建一个视图,通过该视图可以查询到每个部门的部门名称及最低工资。
视图是执行DML操作

如果定义视图的子查询中包含 分组函数 ,group by 子句和 distinct关键字
则不能对视图进行 增加,修改和删除操作

删除视图
drop view view_name

删除视图 并不会删除基本中的数据

索引简介

索引是一种特殊的数据库结构,可以用来快速查询数据库表中的特定记录。索引是提高数据库性能的重要方式。MySQL中,所有的数据类型都可以被索引。

索引的优点是可以提高检索数据的速度,这是创建索引的最主要的原因;对于有依赖关系的子表和父表之间的联合查询时,可以提高查询速度;使用分组和排序子句进行数据查询时,同样可以显著节省查询中分组和排序的时间。

创建索引

CREATE TABLE 表名(

  id int PRIMARY KEY,

   tname varchar(29),

   INDEX(id)
)
创建新用户
1.CREATE USER '用户名'@'localhost' IDENTIFIED BY '密码';
此时新用户没有权限对数据库执行任何操作

为用户提供访问他们将需要的信息的权限
2.GRANT ALL PRIVILEGES ON * . * TO '用户名'@'localhost';

重新加载所有权限才会生效
3.FLUSH PRIVILEGES;

通过SQL 查询表结构

SELECT COLUMN_NAME, COLUMN_TYPE,
COLUMN_COMMENT FROM information_schema.`COLUMNS` 
WHERE TABLE_NAME = 'xxx';

删除列的SQL

lter table table_name drop column column_name

删除表(撤销表)

DROP TABLE table_name

自动增长 AUTO_INCREMENT

建表后添加一个列默认设置默认值

Alter table table_name  add colunm  数据类型  default  默认值

mysql 使用like '%A'的形式进行模糊查询,不会使用索引

解决办法:

将数据以倒序的方式存入数据库,再使用liek 'A%'进行查询即可

例如:

将网址url存入数据库,并且使用模糊查询

1.将网址倒序 www.baidu.com -> moc.udiab.www

2.like 'moc.%'

mysql的事务隔离级别

1.读未提交 (read uncommited)

age字段的原始值为7,事务A修改了age字段的值为12,但事务A处于未提交事务状态。
这时事务B在读取age字段值也是12.

事务B读取到了事务A未提交的数据,出现脏读。

2.读已提交 (read commited)

age字段的原始值为7,事务A修改了age字段的值为12,但事务A处于未提交事务状态。
这时事务B在读取age字段值仍然是7.

但是在事务A提交事务后,这时事务B再查询到的值就是12了,极短时间内两次相同的查询,
但是结果却不一样,这种情况是,不可重复读、幻读

3.可重复读 (repeatable read) mysql默认的隔离级别

age字段的原始值为7,事务A修改了age字段的值为12,事务A处于未提交事务状态。
这时事务B在读取age字段值仍然是7.但是事务A提交事务后,这时事务B再一次读取age字段值仍然还是7

这种情况解决了读已提交模式出现的不可重复读、幻读问题

读已提交 (read commited)这种隔离级别,是如何保证每个事务只能读到自己提交的数据的

mysql的每行记录存在一个隐藏列,用于存储最近一次修改这条记录的事务id
这行记录的每一个修改都会保留,以修改时间为顺序进行链式存储(最新修改->上一次修改->...)

事务A进行查询时,mysql会统计当前处于未提交状态的事务有哪些 例:{事务B,事务C,事务D}
将它们排除掉,然后在链式存储中找到最近一次已提交的事务获取它的值

可重复读 (repeatable read)这种隔离级别,是如何保证每个事务只能读到自己提交的数据的

事务A进行查询时,mysql会统计当前处于未提交状态的事务有哪些 例:{事务B,事务C,事务D}。
但是事务A下一次查询时,事务B已经提交了。但是事务A任然以之前的为准,不会更新未提交状态的事务列表,所以每次读取的值是一样的

mysql乐观锁实现:

使用数据版本(Version)记录机制实现,这是乐观锁最常用的一种实现方式。何谓数据版本?即为数据增加一个版本标识,一般是通过为数据库表增加一个数字类型的 “version” 字段来实现。当读取数据时,将version字段的值一同读出,数据每更新一次,对此version值加一。当我们提交更新的时候,判断数据库表对应记录的当前版本信息与第一次取出来的version值进行比对,如果数据库表当前版本号与第一次取出来的version值相等,则予以更新,否则认为是过期数据

1.数据库表设计

 task : 有三个字段,分别是id,value、version

先读task表的数据(实际上这个表只有一条记录),得到version的值为versionValue

每次更新task表中的value字段时,为了防止发生冲突,需要这样操作

   update task set value = newValue,version =  versionValue + 1   
   where version = versionValue;

只有这条语句执行了,才表明本次更新value字段的值成功

mysql实现悲观锁

要使用悲观锁,我们必须关闭mysql数据库的自动提交属性,因为MySQL默认使用autocommit模式,
也就是说,当你执行一个更新操作后,MySQL会立刻将结果进行提交。

我们可以使用命令设置MySQL为非autocommit模式:

set autocommit=0;

设置完autocommit后,我们就可以执行我们的正常业务了。具体如下:

//0.开始事务

begin;/begin work;/start transaction; (三者选一就可以)

//1.查询出商品信息

select status from t_goods where id=1 for update;

//2.根据商品信息生成订单

insert into t_orders (id,goods_id) values (null,1);

//3.修改商品status为2

update t_goods set status=2 where id = 1;

//4.提交事务

commit;/commit work;

执行select status from t_goods where id=1 for update;后。
我在另外的事务中如果再次执行select status from t_goods where id=1 for update;
则第二个事务会一直等待第一个事务的提交,此时第二个查询处于阻塞的状态,
但是如果我是在第二个事务中执行select status from t_goods where id=1;则能正常查询出数据,不会受第一个事务的影响。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,080评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,422评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,630评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,554评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,662评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,856评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,014评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,752评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,212评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,541评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,687评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,347评论 4 331
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,973评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,777评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,006评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,406评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,576评论 2 349

推荐阅读更多精彩内容