文末有mysql资料mysql
执行顺序:spring
from -> join -> on -> where -> groupby -> avg max .. -> having -> select ->order bysql
SQL语言分类:数据库
data query language服务器
select 字段名 from 表名
select 90
select concat('a', 'bbb');
select 100/1234;
select last_name as '姓名
select DISTINCT department_id
DESC departments;
session
/* 条件运算符: > < <> != >= <= 逻辑运算符: && || ! and or not 模糊查询 : like ,between ,and ,in ,is null like '%%' 匹配不出null值 通配符: % 任意多个字符,包含0个. _ 任意单个字符 默认转义\ 自定义转义: ESCAPE '转义字符' */ #1 查询工资在 12000-17000 的员工姓名和工资 SELECT last_name as '姓名',salary as '工资' FROM employees WHERE salary BETWEEN 12000 and 17000 ; #2 查询员工号为 176 的员工的姓名和部门号和年薪 SELECT employee_id as '编号',last_name as '姓名',job_id as '部门号',salary*12 as '年薪' FROM employees WHERE employee_id =176 ; #3 选择工资不在 5000 到 12000 的员工的姓名和工资 SELECT last_name as '姓名',salary as '工资' FROM employees WHERE salary not BETWEEN 5000 and 17000 ; #4 选择在 20 或 50 号部门工做的员工姓名和部门号 SELECT last_name as '姓名',department_id as '部门号' FROM employees WHERE -- department_id =20 or department_id =50 department_id in(20,50) ; #5 #属性判空 选择公司中没有管理者的员工姓名及 job_id SELECT last_name as '姓名',job_id as '工做号' FROM employees WHERE ISNULL(manager_id) ; #6选择公司中有奖金的员工姓名,工资和奖金级别 SELECT last_name as '姓名',commission_pct as '奖金',salary as "工资" FROM employees WHERE not ISNULL(commission_pct) ; #7 选择员工姓名的第三个字母是 a 的员工姓名 SELECT last_name as '姓名' FROM employees WHERE last_name LIKE '__a%' ; #8 选择姓名中有字母 a 和 e 的员工姓名 SELECT last_name as '姓名' FROM employees WHERE last_name LIKE '%a%e%' or last_name LIKE '%e%a%'; ; #9 显示出表 employees 表中 first_name 以 'e'结尾的员工信息 SELECT last_name as '姓名' FROM employees WHERE last_name LIKE '%e'; ; #10 显示出表 employees 部门编号在 80-100 之间 的姓名、职位 SELECT last_name as '姓名',department_id '部门号' FROM employees WHERE department_id BETWEEN 80 AND 100; ; #11 显示出表 employees 的 manager_id 是 100,101,110 的员工姓名、职位 SELECT last_name as '姓名',job_id as '职位',manager_id FROM employees WHERE manager_id in(100,101,110) ;
#1 查询员工的姓名和部门号和年薪,按年薪降序 按姓名升序 SELECT last_name as name,department_id as dID ,salary*12 as yearsal FROM employees ORDER BY yearsal DESC,last_name ASC #2 选择工资不在 8000 到 17000 的员工的姓名和工资,按工资降序 SELECT last_name as name,salary as sal FROM employees WHERE salary not BETWEEN 8000 and 17000 ORDER BY salary DESC #3 查询邮箱中包含 e 的员工信息,并先按邮箱的字节数降序,再按部门号升序 SELECT department_id as dID,email,LENGTH(email) as '邮箱长度' FROM employees ORDER BY LENGTH(email) DESC,department_id ASC
SELECT LENGTH(TRIM('a' FROM "aaa123aaa")) as '长度'
=> 123SELECT LPAD('aaaaa','10','#')
=> #####aaaaanow :当前时间函数
STR_TO_DATE(str,format):将日期格式的字符转换成指定格式的日期性能
DATE_FORMAT(date,format) :将日期转换成字符code
#1显示系统时间(注:日期+时间) SELECT NOW() #2 计算年薪 SELECT last_name as name,salary,salary*1.2 as newsal FROM employees #3将员工的姓名按首字母排序,并写出姓名的长度(length) SELECT last_name as name ,LENGTH(last_name) as '长度' FROM employees ORDER BY SUBSTR(name,1,1) ASC,LENGTH(name) DESC #4 输出 <last_name> earns <salary> monthly but wants <salary*3> SELECT CONCAT(last_name,' earn ',ROUND(salary),' monthly but wants ',ROUND(salary*3)) as 'Dream Salary' FROM employees #5 /* job grade AD_PRES A ST_MAN B IT_PROG C SA_REP D ST_CLERK E Last_name Job_id Grade king AD_PRES A */ SELECT last_name,job_id, #case 也算一个字段,用逗号分隔 CASE job_id WHEN 'AD_PRES' THEN 'A' WHEN 'ST_MAN' THEN 'B' WHEN 'IT_PROG' THEN 'C' WHEN 'SA_REP' THEN 'D' WHEN 'ST_CLERK' THEN 'E' ELSE 'null' END as 'grade' FROM employees ORDER BY grade ASC
特征:orm
为何使用推荐使用COUNT(*)统计总记录数,根据分组函数的特色,null值不计入,当某个字段为null时,可能会出现漏记.
摘自官网:
InnoDB以相同的方式处理SELECT COUNT(*)和SELECT COUNT(1)操做。没有性能差别。
1.单子段分组:
select 分组函数,分组后的字段 from 表 【where 筛选条件】 -- 分组前的筛选条件 group by 分组的字段 【having 分组后的筛选】 -- 分组函数,筛选知足条件的组 【order by 排序列表】
2.按函数分组
group by 后还可以使用函数,
例子:按员工姓名长度分组,查询每一组的员工个数,筛选员工个数>5的有哪些;
SELECT LENGTH(last_name) as 'length', COUNT(*) FROM employees GROUP BY LENGTH(last_name) HAVING COUNT(*) >3
3.多字段分组
例子:查询每一个部门每一个工种的员工平均工资
SELECT AVG(salary),department_id,job_id FROM employees WHERE not ISNULL(department_id) GROUP BY department_id,job_id ORDER BY AVG(salary) ASC
φ(゜▽゜*)♪
#1.查询各 job_id 的员工工资的最大值,最小值,平均值,总和,并按 job_id 升序 SELECT job_id, MAX(salary),MIN(salary),AVG(salary),SUM(salary) FROM employees GROUP BY job_id ORDER BY job_id ASC #2.查询各个管理者手下员工的最低工资,其中最低工资不能低于 6000, 没有管理者的员工不计算在内 SELECT manager_id, MIN(salary) FROM employees WHERE not ISNULL(manager_id) -- 分组前的筛选条件 GROUP BY manager_id HAVING MIN(salary)>=6000 -- 筛选知足条件的组 ORDER BY manager_id ASC #3.查询员工表中的最大入职时间和最小入职时间的相差天数 SELECT DATEDIFF(MAX(hiredate),MIN(hiredate)) FROM employees
UNION
when use:查新的结果来自多个表,且多个表没有直接的链接关系,但查询的信息一致
特色:
SELECT b.*,g.* FROM boys b,beauty g
表1 有m行,表2 有n行,结果=m*n;
缘由:无有效的链接条件
避免:可使用WHERE 添加有效的链接条件
返回两张表都知足条件的部分.
#(等值链接) #查询每一个城市的部门个数 SELECT city,COUNT(*) FROM locations l,departments d WHERE l.location_id = d.location_id GROUP BY city # 查询有奖金的每一个部门的部门名和部门的领导编号和该部门的最低工资 SELECT d.department_name,d.manager_id ,MIN(e.salary) FROM employees e,departments d WHERE e.department_id =d.department_id AND NOT ISNULL(e.commission_pct) GROUP BY e.department_id #查询每一个国家下的部门个数大于 2 的国家编号 SELECT l.country_id FROM locations l,departments d WHERE l.location_id = d.location_id GROUP BY country_id HAVING COUNT(*)>2 #不等值链接 #依据job_grades给每一个员工工资分等级 SELECT e.salary ,jg.grade_level FROM employees e,job_grades jg WHERE e.salary BETWEEN jg.lowest_sal AND jg.highest_sal ORDER BY e.salary ASC #自链接 #选择指定员工的姓名,员工号,以及他的管理者的姓名和员工号,结果相似于下面的格式 # employees Emp manager Mgr SELECT e.last_name as 'employees' ,e.employee_id as 'Emp' ,m.last_name as' manager',m.employee_id as'Mgr' FROM employees e,employees m WHERE e.manager_id =m.employee_id
外连接的查询结果=主表中的全部记录+从表匹配值(ifnull 则显示null)
左外链接 left join 左边的是主表
右外链接 right join 右边的是主表
全外链接: FULL JOIN (Mysql不支持
)
select <select_list> from A full join B on A.key=B.key where A.key is null or b.key is null
select -- 查询列表 from 表1 -- [链接类型] join 表2 on 链接条件 -- where 筛选条件
#查询beauty中男友状况 SELECT g.`name` ,b.id,b.boyName FROM beauty g LEFT JOIN boys b on g.boyfriend_id =b.id #查询哪个部门没有员工 SELECT d.* ,e.employee_id,e.manager_id FROM departments d LEFT JOIN employees e on d.department_id = e.department_id WHERE e.manager_id is null #查询部门名为 SAL,IT的员工信息 SELECT e.*,d.department_name FROM departments d RIGHT JOIN employees e on d.department_id = e.department_id WHERE d.department_name in('SAL','IT')
即笛卡尔乘积结果
分类:
位置:
特色:
> < <> >= <=
in ,any ,some ,all
#返回job_id与141号员工相同,salary比143号员工多的 员工姓名,job_id,和工资 SELECT last_name,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 )
any:和子查询返回的某一个比较
In/not in : 等于列表中的任意一个
#返回location_id是1400或1700的部门中全部员工姓名 SELECT last_name FROM employees WHERE department_id in ( SELECT department_id FROM departments WHERE location_id in (1400,1700) ) #返回其余工种比job_id为'IT_PROG'工种任一工资低的员工的员工号,姓名,job_id,以及salary SELECT employee_id,last_name,job_id,salary FROM employees WHERE salary < ANY( SELECT salary FROM employees WHERE job_id = 'IT_PROG' ) AND job_id <>'IT_PROG';
#返回员工编号最小,工资最高的信息. SELECT * FROM employees WHERE (employee_id,salary)=( SELECT MIN(employee_id),MAX(salary) FROM employees )
#查询每一个部门的员工个数,显示departments表 SELECT d.* ,( SELECT COUNT(*) FROM employees e WHERE d.department_id=e.department_id ) 统计 FROM departments d -- 27 /* 错误代码 why? SELECT d.* ,( SELECT COUNT(*) FROM employees e WHERE d.department_id=e.department_id ) 'ANS' FROM employees e,departments d 2889 */
#查询每一个部门的平均工资的工资等级 SELECT ag_dep.*,g.grade_level FROM ( SELECT AVG(salary) as ag,department_id FROM employees GROUP BY department_id )ag_dep INNER JOIN job_grades g -- 直接起别名 若是 AS 'g'则会报错 ON ag_dep.ag BETWEEN g.lowest_sal AND g.highest_sal
/* 语法: EXISTS(完整的查询语句) 返回: 0或1 */ #查询没有女友的boy SELECT bo.* FROM boys bo WHERE NOT EXISTS ( SELECT boyfriend_id FROM beauty g WHERE bo.id =g.boyfriend_id ) #链接查询 SELECT b.* FROM boys b LEFT JOIN beauty g on b.id= g.boyfriend_id WHERE g.name is NULL
-- 1. 查询和 Zlotkey 相同部门的员工姓名和工资 SELECT last_name,salary,department_id FROM employees WHERE department_id=( SELECT department_id FROM employees WHERE last_name ='Zlotkey' )#34 -- 2. 查询工资比公司平均工资高的员工的员工号,姓名和工资 SELECT employee_id,last_name,salary FROM employees WHERE salary>( SELECT AVG(salary) FROM employees )#51 -- 3. 查询各部门中工资比本部门平均工资高的员工的员工号, 姓名和工资 SELECT employee_id,last_name,salary FROM ( SELECT AVG(e.salary) ag_sal,e.department_id eid FROM employees e GROUP BY department_id ) tab1 INNER JOIN employees e1 on e1.department_id = tab1.eid WHERE e1.salary >tab1.ag_sal ORDER BY e1.employee_id #38 -- 4. 查询和姓名中包含字母 u 的员工在相同部门的员工的员工号和姓名 SELECT employee_id,last_name FROM employees WHERE department_id in( SELECT DISTINCT department_id FROM employees WHERE last_name LIKE '%u%' )#96 -- 5. 查询在部门的 location_id 为 1700 的部门工做的员工的员工号 SELECT employee_id FROM employees WHERE department_id in( SELECT department_id FROM departments WHERE location_id=1700 )#18 -- 6. 查询管理者是 King 的员工姓名和工资 SELECT last_name,salary FROM employees e WHERE manager_id in( SELECT employee_id FROM employees WHERE last_name ='K_ing' )#14 -- 7. 查询工资最高的员工的姓名,要求 first_name 和 last_name 显示为一列,列名为 姓.名 SELECT CONCAT(first_name,last_name) as "姓名" FROM employees WHERE salary =( SELECT MAX(salary) FROM employees )
select -- 查询列表 from 表1 [type] join 表2-- [链接类型] on 链接条件 -- where 筛选条件 group by 分组字段 having 分组后筛选 order by 排序字段 limit offset ,size; offset = (page-1)*size
data manipulation language
insert into 表名(列名,...) values(值1) -- 一 insert into 表名 set 字段=值,字段=值,... -- 二 #1 插入值类型与列类型一致 ,可调换顺序 ,不可为null的值必须插入值 #2 方式一支持 一次插入多行 + 子查询
update 表名 set 字段=值,字段=值 【where 筛选条件】; -- 1 -- 2 多表更新 update 表1 别名 left|right|inner join 表2 别名 on 链接条件 set 字段=值,字段=值 【where 筛选条件】;
delete from 表名 【where 筛选条件】【limit 条目数】 truncate table 表名 #多表删除 实例 delete g from beauty g inner join boys b on g.boyfriends_id = b.id where b.boyName='xxx';
delete 与 truncate 区别:
data defination language
#建立 CREATE DATABASE if NOT EXISTS boos; #重命名 RENAME DATABASE boos TO books; #设置字符集 ALTER DATABASE boos CHARACTER SET gbk; #删除库 DROP DATABASE boos;
drop table if 表名 exists create table 【if not exists】 表名( 字段名 字段类型(长度) 【约束】, 字段名 字段类型 【约束】, .... 字段名 字段类型 【约束】 ) create table if not exists books( id INT(2) AUTO_INCREMENT, bname VARCHAR(20), privce DOUBLE , PRIMARY KEY (id) )
1.添加列
alter table 表名 add column 列名 类型 【first|after 字段名】;
ALTER TABLE books ADD COLUMN author INT;
2.修改列的类型或约束
alter table 表名 modify column 列名 新类型 【新约束】;
alter table books modify column name DOUBLE UNIQUE;
3.修改列名
alter table 表名 change column 旧列名 新列名 类型;
同时可修改类型
alter table books change bname name varchar(30);
4 .删除列
alter table 表名 drop column 列名;
ALTER TABLE books DROP COLUMN NAME
5.修改表名
alter table 表名 rename 【to】 新表名;
alter table books rename to new_books;
6.表的复制
#一、复制表的结构 create table 表名 like 旧表; CREATE TABLE copyed LIKE new_books #二、复制表的结构+数据 create table 表名 select 查询列表 from 旧表【where 筛选】; CREATE TABLE copy_books SELECT * FROM new_books WHERE 1=1;
整型:tinyint、smallint、mediumint、int/integer、bigint
浮点型:
M = 整数位数+小数位数
D =小数位数
Mysql8中: 若是D=3,插入12.456则会四舍五入为12.5
字符型:char、varchar、binary、varbinary、enum、set、text、blob
char:char(M),最大长度不能超过M,其中M能够省略,默认为1
varchar:可变长度的字符,写法为varchar(M),最大长度不能超过M,其中M不能够省略
日期型:year,date日期 ,time时间, datetime 日期时间
主键:一个表至多有一个主键,但能够有多个惟一
外键:
支持类型 | 是否可起约束名 | |
---|---|---|
列级约束 | 外键约束没有效果 | 不能够 |
表级约束 | 除了非空和默认 | 能够,但对主键无效 |
create table 表名( #列级约束 字段名 字段类型 not null,#非空 字段名 字段类型 primary key,#主键 字段名 字段类型 unique,#惟一 字段名 字段类型 default 值,#默认 #表级约束 constraint 约束名 foreign key(字段名) references 主表(被引用列), constraint fk_stu_major foreign key(majorid) references major(id), constraint 约束名 [约束](字段), -- 约束名 = 别名 ,变量 constraint pk primary key(id) ) show INDEX FROM 表名
自增加列:
Transaction Control Language 事务控制语言
事务:一条或多条sql语句组成一个执行单位,一组sql语句要么都执行要么都不执行
set autocommit=0 start transaction delete from account where id =25 savepoint a #设置保存点 delete from account where id =28 rollback to a; #回滚到a
重点在spring中介绍事务操做
what:虚拟表,经过表动态生成的数据 ,只保存sql逻辑不保存结果
where:
#建立 create VIEW myview1 As SELECT last_name,department_name,job_title FROM employees e join departments d on e.department_id = d.department_id join jobs j on j.job_id = e.job_id SELECT * from myview1 where last_name like '%a%' #修改 create or replace view [视图名] as [查询语句] #删除 drop view [视图名]
系统变量:
全局变量:服务器层面上的,必须拥有super权限才能为系统变量赋值,做用域为整个服务器,也就是针对于全部链接(会话)有效
会话变量:服务器为每个链接的客户端都提供了系统变量,做用域为当前的链接(会话)
show 【global|session 】variables like ''; set 【global|session 】 变量名=值
自定义变量:
用户变量:针对于当前链接(会话)生效
set @变量名=值; select @变量名; set @m =1; set @n = 2; set @sum = @m +@n; select @sum;
局部变量:仅仅在定义它的begin end中有效
declare 变量名 类型 【default 值】;
what :一组预先编译号的SQL语句集合
why use:
create procedure 存储过程名(参数列表) begin [sql 语句] end 参数列表: 参数模式 参数名 参数类型 In stuname varchar(20)
调用: call 存储过程名(实参列表)
delimiter 结束标记:
delimiter $ -- 任意
案例:
IN:
CREATE DEFINER=`root`@`localhost` PROCEDURE `logincheck`(IN username VARCHAR(20),IN password VARCHAR(20)) BEGIN #Routine body goes here... DECLARE result VARCHAR(20) DEFAULT ''; SELECT COUNT(*) INTO result FROM admin WHERE admin.username =username AND admin.`password` =password; SELECT IF (result>0 ,'成功','失败'); END CALL logincheck('admin1','123') #JDBC中 db.connect( "db_host" ).execute_sql( "CALL logincheck('admin1','123')" );
OUT:
CREATE DEFINER=`root`@`localhost` PROCEDURE `findboy`(In butyName VARCHAR(20),OUT boyName VARCHAR(20)) BEGIN #Routine body goes here... SELECT bo.boyName INTO boyName FROM boys bo JOIN beauty g on bo.id = g.boyfriend_id WHERE g.name = butyName; END CALL findboy('小昭',@boyName); SELECT @boyName
区别:
CREATE FUNCTION `函数名`(参数列表) RETURNS 返回类型 BEGIN #Routine body goes here... RETURN 0; END; -------------------- CREATE DEFINER = CURRENT_USER FUNCTION ``() RETURNS integer BEGIN #Routine body goes here... RETURN 0; END; select 函数名(参数列表)
data control language
分支:
CREATE PROCEDURE casse(IN score INT) BEGIN CASE WHEN scorce>=90 THEN SELECT 'A'; WHEN scorce>=90 THEN SELECT 'B'; ELSE SELECT 'C'; END CASE; END; #--------------------------------- CREATE PROCEDURE casse(IN score INT) BEGIN IF search_condition THEN statement_list ELSEIF search_condition THEN statement_list ELSE statement_list END IF; END; #-------------循环------------------- CREATE PROCEDURE casse(IN cnt INT) BEGIN DECLARE i INT DEFAULT 0; WHILE i<=cnt DO INSERT into admin(username,`password`) VALUES(xxx,xxx) END WHILE; END;
连接:https://pan.baidu.com/s/1EeBnOhgMSJjvn35RZtz5sw 提取码:3mji 复制这段内容后打开百度网盘手机App,操做更方便哦