注意:
1.SQL 语言大小写不敏感
2.SQL 可以写在一行或者多行
3.关键字不能被缩写也不能分行
4.各子句一般要分行写
5.使用缩进提高语句的可读性。
打开cmd,输入下列语句
mysql -u root -p
接下来输入你设置的MySQL密码
注:一般不采用这种方式连接数据库。推荐使用可视化数据库界面
show databases;
use 库名;
show databases;
select 字段名1,字段名2,...
from 表名;
select * # *表示所有的字段
from 表名
注意:
1、任何类型的数据和NULL做运算结果为NULL ;
2、dual:伪表(虚拟表)可以省略不写;
select 字段名1 别名1,字段名2 as 别名2,字段名3 "别名3"
from 表名;
注意:如果别名中间有空格那么可以使用双引号或者单引号引起来(一般使用双引号)
select 字段名1,字段名2,...
from 表名
where 过滤条件;
=:等于(不是==)
>: 大于
>=: 大于等于
<: 小于
<=:小于等于
<>: 不等于(也可以写为!=)(建议使用<>)
% : 表示任意个数的任意字符
_ : 表示任意一个字符
\ : 表示转义字符
escape ‘字符’: 指定某字符为转义字符
赋值:=
BETWEEN ... AND ... # 在两个值之间(包含边界)
IN(set) # 等于值列表中的一个
LIKE # 模糊查询
IS NULL # 空值 # 判断空值为NULL 不能用 = NULL,而应使用 is NULL
AND(&&) # 逻辑与
OR(||) # 逻辑或
NOT # 逻辑否
# 查询员工的薪水大于6000的有哪些人
SELECT first_name,salary
FROM employees
WHERE salary>6000;
#查询80号部门员工有哪些
SELECT first_name,department_id
FROM employees
WHERE department_id=80;
# 查询除80号部门其他部门的员工有哪些
SELECT first_name,department_id
FROM employees
WHERE department_id<>80;
# 查询员工的薪水在6000到10000之间的有哪些
SELECT first_name,salary
FROM employees
WHERE salary BETWEEN 6000 AND 10000
# 查询30和50号部门的所有员工
SELECT first_name,department_id
FROM employees
WHERE department_id IN(30,50);
# 查询员工的降级率不为null的员工有哪些
SELECT first_name,commission_pct
FROM employees
WHERE commission_pct IS NOT NULL;
# 查询员工的薪水不在6000到10000之间的员工有哪些
SELECT first_name,salary
FROM emplyees
WHERE salary NOT BETWEEN 6000 AND 10000
# 求员工的姓名中包含f的有哪些
SELECT first_name
FROM employees
WHERE first_name LIKE '%f%';# %表示任意个数的任意字符
# 查询员工的姓名中第二个字符为d的员工有哪些
SELECT first_name
FROM employees
WHERE first_name LIKE '_d%'; # _表示一个任意字符
# 查询员工的姓名中第二个字符为_的员工有哪些
SELECT first_name
FROM employees
WHERE first_name LIKE '_\_%'; # \_内容为_
# escape:指定转义字符
# 例子:
SELECT first_name
FROM employees
WHERE first_name LIKE '_$_%' ESCAPE '$'; # 指定$为转义字符
# 查询员工的姓名中包含a又包含e的有哪些
SELECT first_name
FROM employees
WHERE first_name LIKE '%a%' AND first_name LIKE '%e%';
排序
select 字段名1,字段名2,... from 表名 where 过滤条件 order by 字段名 asc/desc,字段名 asc/desc,...
说明:
1.asc-升序,desc-降序
2.如果不指定排序方式那么默认是升序
# 查询所有员工的姓名和薪水并按照薪水排序-降序
select first_name,salary
from employees
order by salary desc;
# 查询所有员工的姓名和薪水并按照薪水排序-升序
select first_name,salary
from employees
order by salary;
# 查询80号部门的所有员工的姓名和薪水并按照薪水排序-升序
select first_name,salary,department_id
from employees
where department_id=80
order by salary asc;
#查询给员工薪水+1000后的新的薪水命名为new_salary,并对新的薪水进行排序--降序
select first_name,salary,salary+1000 new_salary
from employees
order by new_salary desc;
#查询所有员工的名字,薪水,部门号。并对部门号进行排序-降序
#如果部门号相同再按照薪水排序-升序
select first_name,salary,department_id
from employees
order by department_id desc,salary asc;
查询的字段不在同一张表中,那么就需要用到多表查询
连接方式不同分类:
自连接---非自连接
{非自连接:连接的两张表不是同一张表}
{自连接 : 连接的两张表是同一张表}
等值连接---非等值连接
{等值连接 :连接条件使用的是等号}
{非等值连接:连接条件不止使用等号}
内连接---外连接
{内连接:只获取表中匹配的内容}
{外连接:分为左外连接(除了匹配的内容还包括左表中不匹配的内容)、右外连接(除了匹配的内容还包括由表中不匹配的内容)、满外连接(MySQL不支持)}
语法规则:
sql92语法---sql99语法(主要使用sql99语法)
注意:
1、在多表查询中如果查询的字段是唯一的那么可以在字段名前不用加表名;
2、如果查询的字段不是唯一的那么该字段名前需要加表名;
3、在多表查询中查询的字段名前加表名效率更高;
4、飘号‘’用来区分关键字和字段名;
sql99语法:
select 字段名1,字段名2,...
from 表名1 join 表名2
on 连接条件
join 表名3
on 连接条件
...
where 过滤条件
order by 字段名1 asc/desc,字段名2 asc/desc,...
#sql92语法
#查询员工的姓名和部门名称
select first_name,department_name
from employees,departments
where employees.department_id=departments.department_id;
#查询员工的姓名,部门号和部门名称
select first_name,department_name,employees.department_id
from employees,departments
where employees.department_id=departments.department_id;
#给表起别名
#查询员工的姓名,部门号和部门名称
select e.first_name,d.department_name,e.department_id
from employees e,departments d
where e.department_id=d.department_id;
#产生迪卡尔集的例子
#产生的原因为没有连接条件
select e.first_name,d.department_name,e.department_id
from employees e,departments d
#使用sql99
#非自连接:连接的两张表不是同一张表
#等值连接:连接条件使用的是等号
#内连接:只获取表中匹配的内容
#查询员工的姓名,部门号和部门名称
select e.first_name,d.department_name
from employees e join departments d
on e.department_id = d.department_id;
#sql99
#自连接
#查询员工的姓名及该员工的管理者的姓名
select e1.first_name 员工姓名,e2.first_name 管理者姓名
from employees e1 join employees e2 #e1当员工表,e2当管理者表
on e1.manager_id = e2.employee_id;
#非等值连接
#查询员工的薪水及薪水等级
select e.first_name,e.salary,j.GRADE
from employees e join job_grades j
on e.salary >= j.LOWEST_SAL and e.salary <= j.HIGHEST_SAL;
#内连接:
#查询所有的员工姓名及部门名称
select e.first_name,d.department_name
from employees e join departments d
on e.department_id=d.department_id;
#左外连接:除了匹配的内容还包括左表中不匹配的内容
#需求:查询所有的员工的姓名及员工部门的名称
select e.first_name,d.department_name
from employees e left join departments d
on e.department_id=d.department;
#右外连接:除了匹配的内容还包括右表中不匹配的内容
#查询所有部门名称及部门员工的姓名
select e.first_name,d.department_name
from employees e right join departments d
on e.department_id = d.department_id;
#右外连接
#查询所有的员工和部门名称(包括没有部门的员工和没有员工的部门)
select e.first_name,d.department_name
from employees e right join departments d
on e.department_id=d.department_id;
#查询员工的姓名、部门名称及部门所在城市的名称
select e.first_name,d.department_name,l.city
from employees e join departments d
on e.department_id = d.department_id
join locations l
on d.location_id = l.location_id;
#distinct去重
#查询所有员工的部门的部门号有哪些
select distinct department_id
from employees
where department_id is not NULL;
#MySQL不支持满外连接
#使用union替代
左外连接
union
右外连接
#选择city在Toronto工作的员工的last_name,job_id,department_id,department_name
select e.'last_name',e.'job_id',d.'department_id',d.'department_name',l.'location_id',l.'city'
from employees e join departments d
on e.'departmdnt_id'=d.'department_id'
join locations l
on d.'location_id'=l.'location_id'
where l.'city'='Toronto';
#选择指定员工的姓名,员工号,以及他的管理者的姓名和员工号,结果类似下面的格式
employees Emp# manager Mgr#
kochhar 101 king 100
select e1.first_name employees,e1.employee_id "Emp#",e2.first_name manager,e2.employee_id "Mgr#"
from employees e1 join employees e2 #e1 员工表 e2管理者表
on e1.manager_id=e2.employee_id;
lower('SQL Course'):将字符串内容全部变成小写 upper('SQL Course'):将字符串内容全部变成大写 concat('Hello','World'):字符串拼接 substr('HelloWorld',1,5):截取子串(索引位置从1开始)1:开始的位置。5:长度(偏移量) length('HelloWorld'):内容的长度 instr('HelloWorld','W'):W在字符串中首次出现的位置 lpad(salary,10,'*'):向右对齐,如果内容长度不够10用*补 rpad(salary,10,'*'):向左对齐,如果内容长度不够10用*补 trim('H' from 'HelloWorld'):去除字符串两端指定的字符 replace('abcd','b','m'):将字符串中所有的b替换成m round(45.926,2):四舍五入,2表示保留2位小数 truncate(45.926,0):截断,2表示保留2位小数 mod(1600,300):求余,结果的正负和被模数的正负有关(第一个参数的正负有关) now():日期时间 version():版本
#全部变成小写,全部变成大写
select lower('abcDeFgKl'),upper('abcDeFgKl');
#全部变成小写,全部变成大写
select lower(first_name),upper(last_name)
from employees;
#字符串拼接
select concat(first_name,'-',last_name)
from employees;
#截取子串
select substr('abcdef',2,3);
#内容长度
select first_name,length(first_name)
from employees;
#c在字符串中首次出现的位置
select instr('abcdc','c');
#向左对齐,向右对齐
select lpad(salary,10,'*'),rpad(salary,10,'*')
from employees;
#去除字符串两端指定的字符
select trim('H' from 'HHHHHAHHHHBHHHHH');
#将字符串中所有c的替换成C
select replace('abccccdba','c','C');
#四舍五入,保留2位小数,保留1位小数,保留0位小数,保留到-1位
select round(45.926,2),round(45.926,1),round(45.926,0).round(45.926,-1);
#截断,保留2位小数,保留1位小数,不保留小数,保留到十位
select truncate(45.926,2),truncate(45.926,1),truncate(45.926,0),truncate(45.926,-1);
#求余,3对2取余,-3对2取余,3对-2取余,-3对-2取余
select mod(3,2),mod(-3,2),mod(3,-2),mod(-3,-2);
#日期时间
select now();
#版本
select version();
#做一个查询,产生下面的结果:
# earns monthly but wants Dream Salary
#King earns 24000 mothly but wants 72000
select concat(last_name,' earns ',truncate(salary,0),' mothly but wants ',truncate(salary*3,0) "Dream Salary"
from employees;
ifnull(字段名,默认值):如果字段的内容为null用默认值替换 case表达式: 第一种: case 字段名 when 值1 then 返回值1 when 值2 then 返回值2 when 值3 then 返回值3 else 返回值n end 第二种: case when 表达式1 then 返回值1 when 表达式2 then 返回值2 when 表达式3 then 返回值3 else 返回值n end
#ifnull(字段名,默认值)
select salary+ifnull(commission_pct,0)*salary 工资
from employees;
#case表达式(第一种)
#查询部门号为10,20,30的员工信息,若部门号为10,则打印其工资的1.1倍
#20号部门,则打印其工资的1.2倍,30号部门打印其工资的1.3倍数
select department_id,salary,case department_id
when 10 then salary*1.1
when 20 then salary*1.2
when 30 then salary*1.3
else salary
end as "new_salary"
from employees
where dapartment_id in(10,20,30);
#case表达式(第二种)
#查询所有员工的薪水如果大于10000显示1,小于10000显示2,等于10000显示3
select salary,case
when salary>10000 then "1"
when salary<10000 then "2"
else "3"
end as des
from employees;
avg():求平均值 sum():求和 注意:上面的函数只能对数值类型做运算 max():求最大值 min():求最小值 count():统计结果的数量 用法如下: count(字段名):统计查询的结果中该字段内容不为null的有多少条 count(*):统计查询的结果有多少条数据 count(数值):和count(*)的作用一样,count(数值)效率高一些
#多行函数
#求所有员工薪水的最大值,最小值,平均值,总和
select max(salary),min(salary),avg(salary),sum(salary)
from employees;
#注意下面写法不对
#select后面出现组函数后将不能再出现其他字段,除非该字段出现在group by后面
select first_name,avg(salary)
from employees;
#count用法
select count(commission_pct),count(*),count(1)
from employees;
#求平均值时是否包含null?(不包含)
select sum(commission_pct)/107,sum(commission_pct)/35,AVG(commission_pct)
from employees;
#分组 select 字段名1,字段名2,... from 表名 where 过滤条件 group by 字段名1,字段名2,... having 过滤条件
注意:
where 和 having 的区别?
1.where是在分组前进行过滤,having是在分组后过滤
2.where后面不能使用组函数,having后面可以使用组函数
#查询各部门中最高薪水
select department_id,max(salary)
from employees
where department_id is not null
group by department_id;
#查询各部门中最高薪水并按照最高薪水进行排序-降序
select department_id,AVG(salary) a_s
from employees
where department_id is not null
group by department_id
order by a_s desc;
#查询10,20,30部门的平均薪水大于5000的有哪几个部门
方法一:(效率高)
select department_id,avg(salary)
from employees
where department_id in(10,20,30)
group by department_id
having avg(salary)>5000;
方法二:
select deoartment_idmavg(salary)
from employees
group by dapartment_id
having department_id in(10,20,30) and avg(salary)>5000;
子查询: -在一个a查询语句中在嵌套一个查询语句b,b语句叫作子查询(内查询)a语句叫作主查询(外查询) 子查询分类: -单行子查询:子查询的结果只有一条 -多行子查询:子查询的结果有多条
#谁的工资比Abel高?
#方式一:
#①查询Abel的工资
select salary
from emloyees
where last_name='Abel';
#②查询工资高于11000的员工
select last_name,salary
from employees
where salary>11000;
#方式二:自连接
select e1.'last_name',e1.'salary'
from employees e1 join employees e2
on e1.'salary'>e2.'salary' and e2.'last_name'='Abel';
#方式三:子查询
select last_name,salary
from employees
where salary>(
select salary
from employees
where last_name='Abel'
);
#返回job_id与141号员工相同,salary比143号员工多的员工姓名,job_id和工资
#方式一:
#①查询141号员工的job_id
select job_id
from employees
where employee_id=141;#ST_CLERK
#②查询143号员工的薪水
select salary
from employees
where employee_id=143;#2600
#③查询job_id为ST_CLERK薪水大于2600的员工
select job_id,salary
from employees
where job_id='ST_CLERK' and salary>2600;
#方式二:
select job_id,salary
from employees
where job_id=(
select job_id
from employees
where employee_id=141
) and salary>(
select salary
from employees
where employee_id=143
);
#返回公司工资最少的员工的last_name,job_id和salary
select last_name,job_id,salary
from employees
where salary=(
select min(salary)
from employees
);
#查询最低工资大于50号部门最低工资的部门id和其最低工资
select deaprtment_id,min(salary)
from employees
where dapartment_id is not null
group by department_id
having min(salary) > (
#50号部门最低薪水
select min(salary)
from employees
where department_id=50
);
#返回其他部门中比job_id为'IT_PROG'部门任一工资低的员工的员工号、姓名、job_id以及salary
select employee_id,last_name.job_id,salary
from employees
where salary 'IT_PROG';
#返回其他部门中比job_id为'IT_PROG'部门所有工资都低的员工的员工号、姓名、job_id以及salary
select employee_id,last_name,job_id,salary
from employees
where salary < all(
#查询IT部门所有员工的薪水
select distinct salary
from employees
where job_id='IT_PROG'
) and job_id <> 'IT_PROG';
#查询各部门中工资比本部门平均工资高的员工的员工号,姓名和工资
select e.'first_name',e.'salary',t.a_s
from employees e join(
select department_id,avg(salary) a_s
from employees
group by department_id
)t
on e.'department_id'=t.department_id and e.'salary'>t.a_s;
#查看所有的库 show databese #选库 use myemployees; #查看库的信息 show create database 库名 #创建库 create database [if not exists] 库名 [character set '编码集'] (if not exists:加上该关键字库存在则不报错,如果没有该关键字库存在则报错) (character set '编码集':指定库的编码集) #修改库的编码集 alter database 库名 character set '编码集'; #查看系统中的属性和值 show variables like '%char%'; #删除库 drop database [if exists] 库名;
#查看所有的表 show tables; #查看表结构 desc employees; #查看表的信息 show create table 表名; #创建表 方式一: create table [if not exists] 表名 ( 字段名1 类型1, 字段名2 类型2, 字段名3 类型3, ... 字段名n 类型n )character set '编码集'; 例: create table if not exists emp( id int, ename varchar(20) )character set 'gbk'; 方式二:(基于查询结果创建一张新表) create table emp3 as select first_name,salary from myemployees.employees;#库名.表名 #方式三:基于现有的表结构创建一张新表(表中没有内容) create table [if not exists] 库名 like 库名.表名; #删除表 drop table [if exists] 表名;
int:从-2^31到2^31-1的整型数据。存储大小为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<=6
date:日期型数据,格式‘YYYY-MM-DD’
blob:二进制形式的长文本数据,最大可达4G
text:长文本数据,最大可达4G
#向表中添加、删除、修改列: alter table add/drop/change/modify [column] ...... #向表中添加列 alter table 表名 add [column] 字段名 字段的类型; 例: alter table emp2 add column age int; #修改列的名字 alter table 表名 change golumn 原字段名 新字段名 字段的类型; 例: alter table emp2 change age age2 int; #修改字段的类型 alter table 表名 modify column 字段名 字段的类型; 例: alter table emp2 modify column age2 varchar(20); #删除字段 alter table 表名 drop cilumn 字段名; # 例: alter table emp2 drop column age2; #修改表的名字: alter table 原表名 rename to 新表名; #例: alter table stu rename to stu2;
#向表中插入单行数据: insert into 表名(字段名1,字段名2,...) values (值1,值2,...); #向表中插入多行数据: insert into 表名(字段名1,字段名2,...) values (值1,值2,...),(值1,值2,...),...; #将查询的结果插入表中 insert into 表名(字段名1,字段名2,...) select 字段名1,字段名2,...from xxx .....; #修改数据 update 表名 set 字段名1=值1,字段名2=值2,... where 过滤条件 #删除数据 delete from 表名 where 过滤条件;
# 插入单行数据
insert into student(id,name,age,sid) values(1,'longge',18,1000);
#如果插入的是全字段那么可以省略表名后的字段名
insert into studnet values(3,'longge',18,1000);
#向表中插入多行数据
insert into student values(4,'zejie',16,2001),(5,'longjie',16,2002);
#将查询的结果插入到表中
insert into student(id,name)
select employee_id,first_name
from myemployees.'employees';
#注意:
#查询的字段的类型和个数要和被插入的字段的类型和个数保持一致
#修改指定数据
update student set age=19,sid=1001 where id=2;
#修改表中所有的内容
update student set age=20,sid=3000;
# 删除表中指定数据
delete from student where id=1;
#删除表中所有数据
delete from student;
#事务: #一组逻辑操作单元,使数据从一种状态变换到另一种状态 #案例: # AA给CC转账1000元 try{ 事务开启 AA减去1000元的操作; System.out.println(1/0); CC加上1000元的操作; 事务提交 }catch(Exception e){ 事务回滚; } 遇到的问题:可能会发生AA的操作成功但是CC的操作失败 解决思路:将AA和CC的操作看成一个整体看成一个整体要么都成功要么都失败 #事务开启--静止自动提交 set autocommit=false; #事务回滚 rollback; #事务提交---一旦提交将不能回滚 commit; #允许自动提交(一旦事务结束一定要允许自动提交-要不然后面的操作仍处在事务中) set autocommit=true;
delete from 和 truncate table 的区别?
1. truncate table 不能事务回滚,delete from 可以
2. 如果确定删除后不需要回滚那么可以使用 truncate table 效率高
#约束 #有以下六种约束: # not null 非空约束,规定某个字段不能为空 # unique 唯一约束,规定某个字段在整个表中是唯一的 # primary key 主键(非空且唯一) # foreign key 外键 # check 检查约束(MySQL不支持) # default 默认值 #约束的分类: # 列级约束:同时只能约束一列 # 表级约束:同时可以约束多列 #创建表时添加约束(理解) # 1.创建表时添加列级约束 # 2.创建表时添加表级约束 #创建表后添加约束(了解)
#创建表时添加列级约束
create table emp(
id int primary key, #主键
name varchar(20) not null, #非空
sid int unique, #唯一
age int default 18 #默认值
);
#表级约束 # (注意:not null,default只有列级约束) # 当添加唯一,主键,外键约束时会自动给约束的字段创建索引 #主键 constraint 索引名 primary key(字段名1,字段名2,...) #唯一 constraint 索引名 unique(字段名1,字段名2,...) #外键约束 constraint 索引名 foreign key(本表的字段名) references 主表表名(主表字段名) #[ 1.创建表时先创建主表还是从表? @先创建主表再创建从表 2.添加数据时先往主表还是从表添加? @主表 3.删除数据时先删除主表还是从表? @从表 ]
#补充:
# auto_increment:自增
#例:
create table emp4(
id int primary key auto_increment,
name varchar(20)
);
# on delete casecade:级联删除
#创建表时添加表级约束
#主键
create table emp2(
id int,
sid int,
name varchar(20),
constraint emp2_id_sid primary key(id,sid)
);
#唯一
create table emp3(
id int,
sid int,
name varchar(20),
constraint emp3_id_sid unique(id,sid)
);
#外键约束
#主表
create table dept(
dept_id int auto_increment primary key,
dept_name varchar(20)
);
#从表
create table emp(
emp_id int auto_increment primary key,
last_name varchar(15),
dept_id int,
constraint emp_dept_id_fk foreign key(dept_id) references dept(dept_id)
);
#添加数据(只有主表中有了10号部门从表中才能使用10号部门)
insert into dept(dept_id,dept_name) values(10,'HR');
insert into emp(last_name,dept_id) values('longge',10);
#删除数据
#删除10号部门得先把10号部门的人删除掉(改成其他部门)再删除10号部门
delete from emp where emp_id=2;
delete from dept where dept_id=10;
#===============================================================#
#主表
create table dept2(
dept_id int auto_increment primary key,
dept_name varchar(20)
);
#从表
create table emp2(
emp_id int auto_increment primary key,
last_name varchar(15),
dept_id int,
constraint em2p_dept_id_fk foreign key(dept_id) references dept(dept_id) on delete cascade
);
#删除10号部门的时候就把10号部门里所有的人全部删除(级联删除--慎用)
delete from dept2 where dept_id=10;
#创建表后添加约束(了解即可) primary key 添加约束:alter table 表名 add primary key (字段名) 修改约束:alter table 表名 modify 字段名 类型 primary key 删除约束:alter table 表名 drop primary key 例: alter table student add primary key(id); alter table student modify id int primary key; alter table student drop primary key; unique: 添加约束:alter table 表名 add unique(字段名) 添加约束:alter table 表名 add constraint 索引名 unique(字段名) 修改约束:alter table 表名 modify 字段名 类型 unique 删除约束:alter table 表名 drop index 索引名 例: alter table student add unique(sid);#使用该方式添加唯一约束索引的名字默认为字段名 alter table student drop index sid; alter table student student add constraint student_name unique(name); alter table student modify sid int unique;
#分页 limit 索引位置,数据的条数 例: select * from employees limit 10,10; 分页公式:limit (页数-1)*每页条数,每页条数
持续更新...