mysql 增删改查和常用函数

插入: 

// 插入单行数据
INSERT INTO table(c1,c2,...)
VALUES 
   (v11,v12,...);

// 插入多行数据
INSERT INTO table(c1,c2,...)
VALUES 
   (v11,v12,...),
   (v21,v22,...),
    ...
   (vnn,vn2,...);

 

高级插入

 insert into b(a, b, c)  select d,e,f from b;

 create table test as select * from dept; --从已知表复制数据和结构  

 create table test as select * from dept where 1=2; --从已知表复制结构但不包括数据  

查询

所有的select 关键字

select distinct *  from table_name
	where 
	group by 
	having 
	order by
	limit a,b

必须存在的有: 
select 
	* 可以换成任意的一个或多个字段名称  
	from
	table_name
#注意: 关键字的顺序是固定的不能随意变化

where 条件

select * from  table_name
where 


where 后面可以是 

1.比较运算符 
	>  <  >=  <=  =  != 
	
2.成员运算符
	in  not in    后面是一个set

3.逻辑运算符 
	and or not 	
	not 要放在表达式的前面   and 和 or 放到两个表达式中间 
4.模糊查询 
	like 
	% 表示 任意个数的任意字符
	_ 表示一个任意字符
5 IS NULL
A Comprehensive Look at MySQL IS NULL Operator
语法
value IS [NOT] NULL
注意:NULL表示无值,它与0、空字符、false不同

 #
 请查询 姓小的  数学小于 80 分  并且  英语 > 20分   的人的 数学成绩
 select math,name  from stu where math < 80 and english > 20 and name like "小%"; 

	

distinct 去除重复记录

select distinct * from stu; 
# 注意仅当查询结果中所有字段全都相同时 才算重复的记录

指定字段

1.星号表示所有字段
2.手动指定需要查询的字段
3.还可也是四则运算   
4.聚合函数 


#请查询  英语及格的人的 平均分 
select name,(math+english) / 2 平均分 from stu where english >= 60;

取别名

select name,math+english as 总分 from stu where name = "赵云";

as 可以省略 

统计函数

​ 也称之为聚合函数, 将一堆数据经过计算得出一个结果

求和   sum(字段名)
平均数  avg(字段名)
最大值  max(字段名)
最小值  min(字段名)
个数    count(字段名)    # 字段名称可以使用* 代替   另外如果字段为空会被忽略

可以用在  字段的位置  或是分组的后面   
例如: 查询所有人的平均工资  
select avg(salary) from emp

错误案例: 查询工资最高的人的姓名 
select name,max(salary) from emp; 
	#默认显示的第一个name  因为name有很多行  而max(salary) 只有一行    两列的行数不匹配
	# 不应该这么写 逻辑错误
select name from emp where salary = max(salary);
	# 报错  
	# 原因: 伪代码
 for line in file:
       if salary = max(salary)  # 
    #分析  where 读取满足条件的一行  ,max()先要拿到所有数据 才能求最大值,
    #这里由于读取没有完成所有无法 求出最大值
#结论  where 后面不能使用聚合函数 

group by

group 是分组的意思 即将一个整体按照某个特征或依据来分为不同的部分

为什么要分组 分组是为了统计,例如统计男性有几个 女性有几个

语法:
select xxx from table_name group by 字段名称;

需求:统计每个性别有几个人 
select sex,count(*) from emp group by sex;

需求: 查询每个性别有几个 并且显示名字
select name,sex,count(*) from emp group by sex;

# mysql 5.6下  查询的结果是name仅显示该分组下的第一个  
# 5.7以上则直接报错 ,5.6也可以手动开启这个功能  

# 我们可以用group_concat 将分组之外的字段 做一个拼接 ,但是这是没有意义
# 如果要查询某个性别下的所有信息 直接使用where 即可  

#结论: 只有出现在了group by 后面得字段才能出现在select的后面

having

​ 用于过滤,但是与where不同的是,having使用在分组之后

案例:

# 求出平均工资大于5000的部门信息 
select dept,avg(salary) from emp  group by dept having avg(salary) > 5000;


#查询 部门人数少于3的 部门名称 人员名称 人员个数

select dept,group_concat(name),count(*) from emp group by dept having count(*) < 3;

order

根据某个字段排序

语法:
select * from table_name order by 字段名称;
# 默认是升序

# 改为降序 
select * from table_name order by 字段名称 desc;

# 多个字段  第一个相同在按照第二个    asc 表示升序
select * from table_name order by 字段名称1 desc,字段名称2 asc;


案例:
select * from  emp order by salary desc,id desc;

limit (主要用于数据分页)

用于限制要显示的记录数量

语法1:
select * from table_name limit 个数;
语法2:
select * from table_name limit 起始位置,个数;


# 查询前三条 
select * from  emp limit 3;

# 从第三条开始 查询3条   3-5
select * from  emp limit 2,3;


#  注意:起始位置 从0开始

# 经典的使用场景:分页显示  
1.每一页显示的条数   a  = 3
2.明确当前页数   b = 2
3.计算起始位置   c = (b-1) * a      


select * from emp limit 0,3;
select * from emp limit 3,3;
select * from emp limit 6,3;


# django 提供了现成的分页组件  但是它是先查询所有数据 丢到列表中 再取出数据   这样如果数据量太大可能会有问题 

子查询

​ 将一个查询语句的结果作为另一个查询语句的条件或是数据来源

​ 当我们一次性查不到想要数据时就需要使用子查询

in 关键字子查询

​ 当内层查询 (括号内的) 结果会有多个结果时, 不能使用 = 必须是in ,另外子查询必须只能包含一列数据

​ 需求: 指定一个部门名称,获取改部门下的所有员工信息

1.查询出 平均年龄 大于25的部门编号

select  dept_id from emp  group by  dept_id  having avg(age) > 25;



2.再根据编号查询部门的名称  

select name from  dept where id in (select  dept_id from emp  group by  dept_id  having avg(age) > 25);

子查询的思路:
1.要分析 查到最终的数据 到底有哪些步骤 
2.根据步骤写出对应的sql语句
3.把上一个步骤的sql语句丢到下一个sql语句中作为条件 

exists 关键字子查询

当内层查询 有结果时 外层才会执行

 案例:
 select* from dept where exists (select * from dept where id = 1);
 # 由于内层查询产生了结果 所以 执行了外层查询dept的所有数据 

ANY = SOME             #表示满足某一个
ALL                             #表示满足所有的 


>SELECT IDD FROM table1
WHERE AGE > ANY (SELECT AGE FROM table1);                                    #结果如下图12
……

组合查询(UNION)

#结果合并,对应列数和数据类型必须相同
UNION ALL #表示不去重复
UNION #表示去重

>SELECT IDD ,AGE FROM table1                                                 #结果如下图14
WHERE AGE > 20
UNION ALL
SELECT IDD ,AGE FROM table1
WHERE AGE < 20

UNION必须由两条或两条以上的SELECT语句组成,语句之间用关键字UNION分隔(因此,如果组合四条SELECT语句,将要使用三个UNION关键字)。
UNION中的每个查询必须包含相同的列、表达式或聚集函数(不过,各个列不需要以相同的次序列出)。
列数据类型必须兼容:类型不必完全相同,但必须是可以隐含转换的类型(例如,不同的数值类型或不同的日期类型)。
ORDER BY子句排序。在用UNION组合查询时,只能使用一条ORDER BY子句,它必须位于最后一条SELECT语句之后。
UNION和JOIN的区别

正则表达式查询

# '^b' 表示以b开头的记录
>SELECT * FROM table1
WHERE NAME REGEXP '^b';                                                      #结果如下图15

# 'i$' 表示以i结尾的记录
>SELECT * FROM table1
WHERE NAME REGEXP 'i$';                                                      #结果如下图15

# 'h.o'表示h-o三个字符匹配的记录
>SELECT * FROM table1
WHERE NAME REGEXP 'h.o';                                                     #结果如下图15

# 'Li+'表示以L开头后面至少跟一个i
>SELECT * FROM table1
WHERE NAME REGEXP 'Li+';                                                     #结果如下图16

# 'L*i'表示i前面有若干个L,可以为0个
>SELECT * FROM table1
WHERE NAME REGEXP 'L*i';                                                     #结果如下图16

# 'iu' 表示包含'iu'的记录
>SELECT * FROM table1
WHERE NAME REGEXP 'iu';                                                      #结果如下图17

#[abc] 表示包含a、b、c中任意一个
#[^abc] 表示不包含a、b、c中所有的? ?????
>SELECT * FROM table1
WHERE NAME REGEXP [abc];
>SELECT * FROM table1
WHERE NAME REGEXP [^abc];                                                   #结果如下图18

#i{2,m}表示包含i连续出现至少2次,最多m次

多表查询

笛卡尔积查询

select * from   table1,table2,......

# 笛卡尔积查询的结果会出现大量的错误数据即,数据关联关系错误!
添加过滤条件 从表外键值 等于 主表的主键值

# 并且会产生重复的字段信息  例如员工里的 部门编号  和 部门表的id字段 
在select 后指定需要查询的字段名称 

案例:
select  dept.name 部门 ,dept.id 部门编号,emp.name 姓名,emp.id 员工编号,sex from emp ,dept where dept.id = dept_id;

内连接查询:

本质上就是笛卡尔积查询

语法:
select * from  table1 inner join table2;
案例:
select * from  emp inner join dept where dept_id = dept.id;

inner可以省略
select * from  emp join dept where dept_id = dept.id;

左外连接查询

左边的表无论是否能够匹配都要完整显示

右边的仅展示匹配上的记录

需求: 要查询所有员工以及其所属的部门信息 
select * from emp left join dept on dept_id = dept.id;
注意: 在外连接查询中不能使用where 关键字 必须使用on专门来做表的对应关系   

右外连接查询

右边的表无论是否能够匹配都要完整显示

左边的仅展示匹配上的记录

需求: 要查询所有部门以及其对应的员工信息 
select * from emp right join dept on dept_id = dept.id;

全外连接查询

无论是否匹配成功 两边表的数据都要全部显示

需求:查询所有员工与所有部门的对应关系  
select * from emp full join dept on dept_id = dept.id;

注意:mysql不支持全外连接 


我们可以将 左外连接查询的结果  和 右外连接查询的结果 做一个合并  
select * from emp left join dept on dept_id = dept.id
union
select * from emp right join dept on dept_id = dept.id;

 
union的用法:
select * from emp
union 
select * from emp;

# union将自动去除重复的记录  
# union all 不去重复 


select sex,name from emp 
union 
select * from dept;
# 注意  union 必须保证两个查询结果 列数相同  一般用在多个结果结构完全一致时

总结: 外连接查询 查到的是没有对应关系的记录,但是这样的数据原本就是有问题的,所以最常用的是内连接查询

内连接表示 只显示匹配成功的记录

外连接 没有匹配成功的也要实现

多表查询案例:

create table stu(id int primary key auto_increment,name char(10));

create table tea(id int primary key auto_increment,name char(10));

create table tsr(id int primary key auto_increment,t_id int,s_id int,
foreign key(s_id) references stu(id),
foreign key(t_id) references tea(id));

insert into stu values(null,"张三"),(null,"李四");
insert into tea values(null,"egon"),(null,"wer");
insert into tsr values(null,1,1),(null,1,2),(null,2,2);


#egon老师教过哪些人? 
select tea.name,stu.name from tea join tsr join stu
on 
tea.id = t_id and stu.id = s_id
where tea.name = "egon";


# 子查询实现 
select * from stu where id in (select s_id from tsr where t_id = (select id from tea where name = "egon"));

小结:

select [distinct] *|字段名|四则运算|函数  from table_name
	where    比较运算符   逻辑运算符    成员运算符   区间  between and  模糊匹配 like   exists   																	regexp 正则匹配
	group by    
	having   通常根聚合函数  count sum max  min avg 
	order by 
	limit a,b

子查询

多表查询

笛卡尔积 内连接 外连接

内连接最常用

通常一个需求 可以用连表 也可以 用子查询

like:

select * from users where email like '303578599%'

当起始不是模糊查询时,其实是可以用索引的

select * from users where email like '%303578599%'

如果起始就是模糊查询,就要全表扫描了

分组查询总结:

1.WHERE子句从数据源中去掉不符合其搜索条件的数据

2.GROUP BY子句搜集数据行到各个组中

3.统计函数为各个组计算统计值

4.HAVING子句去掉不符合其组搜索条件的各组数据行

5使用GROUP BY时,select后面出现的内容要么为聚合函数,要么为group by后面出现的内容

递归查询 

Select * from …. Where [结果过滤条件语句]  

Start with  [起始条件过滤语句]  

Connect by prior [中间记录过滤条件语句]   


例子 

Select * from company t Where t.flag=1  

Start with  t.company_id=50500000  

Connect by prior t.company_id=t.parent_id  


说明: 

1.   select [level],column,expr from table [where condition]  

2.   [start with] //[起点]  

3.   [connect by prior + 主键=外键 或 外键=主键]  


a.自顶向下: 左边放主键,右边放外键。 
b.自底向上: 右边放主键,左边放外键。 
c.level(伪列)层次的级别,不固定值。 

更新

UPDATE [LOW_PRIORITY] [IGNORE] table_name 
SET 
    column_name1 = expr1,
    column_name2 = expr2,
    ...
[WHERE
    condition];

UPDATE支持两种修饰符:

LOW_PRIORITY:延迟更新操作直到当前表没有读取操作,不过只有部分存储引擎支持该修饰符,比如:MyISAM, MERGE, MEMORY
IGNORE:允许Mysql在发生错误时继续更新操作

更新操作关联本表  :

查询逻辑  先查找内层数据,在更新外层表,内层数据需要表重命名 as t

update sys_auth set auth_parent_id=

(select * from (select id from sys_auth where auth_code='002025') as t)

where auth_code in('002025001', '002025002‘);

更新操作关联其他表:

查询逻辑 先查找外层数据,再执行内层查询,再更新外层。

UPDATE client_basic_info info  SET manager_phone = (
SELECT user_phone
FROM crm_staff_dk
WHERE invite_code = info.audit_person_code 
)WHERE info.audit_person_code!=''

Delete:

DELETE FROM table_name
WHERE condition;

函数:

一、字符串函数【比较常用,需要掌握】

1、 concat(s1,s2,...,sn) #把传入的参数连接成一个字符串

select concat('abc','def');

select concat(name,' age is ',age) from users;

2、insert(str,m,n,inser_str) #将str的从m位置开始的n个字符替换为inser_str

select insert('abcdef',2,3,'123456');

select insert(name,3,2,'HAHA') from users;

select insert(name,2,2,'00') from users;

3、lower(str)/upper(str) #将字符串str转换成小写/大写

select lower('HELLO'),upper('hello');

select lower('HELLO') as 'HELLO',upper('hello')as 'HELLO';

select * from users where upper(name) = 'AAA';

4、left(str,n)  right(str,n) #分别返回str最左边/最右边的n个字符,如果n<=> NULL 则任何东西不返回

select left('123',3),right('123456',3),left('123',NULL);

5、lpad(str,n,pad)/rpad(str,n,pad) #用字符串pad对str的最左边/最右边进行填充,直到满足str含有n个字符为止

select name,lpad(name,10,'#'), rpad(name,10,'@') from users;

6、trim(str)/ltrim(str)/rtrim(str) #去除字符串str左右空格/左空格/右空格

select concat('#',trim(" abc "),'#'),concat('#',ltrim(' abc '),'#'),concat('#',rtrim(' abc '),'#');

7、replace(str,sear_str,sub_str) #将字符串str中所有出现的sear_str字符串替换为sub_str

select replace('abcdefgabcd','cd','XXX') ;

8、strcmp(str1,str2) #以ASCII码比较字符串str1,str2,返回-1(str1< str2)/0(str1= str2) /1(str1 > str2)

select strcmp('aa','bb'),strcmp('aa','aa'),strcmp('bb','aa');

9、substring(str,n,m) #返回字符串str中从n起,m个字符长度的字符串

selectsubstring('abcdef',2,3);

selectname,substring(name,1,2) as subname from users;

二、数值函数

1、abs(x) #返回x的绝对值

selectabs(10),abs(-10);

selectabs(age) from users;

2、ceil(x) #返回大于x的最小整数

3、floor(x) #返回小于x的最大整数

selectceil(2.1),ceil(2.5),ceil(2.9),floor(2.1),floor(2.5),floor(2.9);

4、mod(x,y) #返回x/y的模,与x%y作用相同

selectmod(null,11);

5、rand() #返回0~1之间的随机数

selectrand();

selectceil(rand() * 100); #取0~100之间的整数随机数

selectfloor(rand() * 100);

6、round(n,m) #返回n四舍五入之后含有m位小数的值,m值默认为0

selectround(1.23);

selectround(1.456,2);

7、truncate(n,m) #返回数字n被截断为m位小数的数值

selecttruncate(1.234,2);

selecttruncate(1.235,2),round(1.235,2);

三:日期函数:

当前日期,当前时间,当前日期+时间,当前时间戳,把时间戳转化为日期+时间。

select CURDATE(),CURTIME(),NOW() ,UNIX_TIMESTAMP(NOW()), FROM_UNIXTIME(unix_timestamp(NOW()));

select month(create_time) from union_showtime;

select year(create_time) from union_showtime;

select day(create_time) from union_showtime;

…  week hour minute second 

select monthname(create_time) from t_union_showtime;

select  date_format('2015-1-8',"%Y-%m-%d %H:%i%s") from t_union_showtime;

create_time 是datetime 类型的也可以:

select  date_format(create_time,"%Y-%m-%d %H:%i%s") from t_union_showtime;

日期格式:

date_format(now(),"%Y-%M-%D%H:%I%S") #将当期时间格式化

select date_format(now(),"%Y-%m-%d %H:%i%s");

select date_format(now(),"%y%m%d %H:%i%s");

四控制流向的函数:

select IF(month(create_time)=1,1,0) from t_union_showtime;

select CASE month(create_time) WHEN 11 THEN 1 ELSE 2 END from t_union_showtime;

select  IFNULL(create_time,0) from t_union_showtime;

五、其他函数

1、database() #当前数据库

2、version() #当前数据库版本

3、user() #当前登录用户

select database();

4、inet_aton(ip) #ip地址的网络字节顺序

select inet_aton('192.168.139.1');

5、inet_ntoa #返回数字所代表的ip

selectinet_ntoa(3232271105);

6、password(str) #返回加密的str字符串

select password("123456"); #返回一个41位长的加密字符串,只是用于给MySQL系统用户进行加密

7、md5() #在应用程序中进行数据加密,比如在C++程序中

select md5(“123456”);

8

加密函数ENCODE(string,pass),可以使用字符串pass来加密字符串string。

select ENCODE('123456',"KEY");
解密函数:

select DECODE('PASSWORD','KEY');

你可能感兴趣的:(mysql,mysql,sql,php)