SQL温故
Posted 白玉梁
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SQL温故相关的知识,希望对你有一定的参考价值。
以上来自于W3CSchool!
常用语法:distinct , in , like , order by , limit , group by , between , join…
单表增删改查案例略…
多表查询案例(两个表user和order,order表中存有user表中的id):
-
查询出user表和order表所有匹配到的行(只返回匹配到的):
注意:order加了引号是因为表名与sql关键字起了冲突,实际开发中应尽量避免这种情况出现!select u.username,o.order_no from booksmanger.user u,`order` o where u.id=o.user_id;
-
等同于join、inner join:
select u.username,o.order_no from booksmanger.user as u join `order` as o on u.id=o.user_id
select u.username,o.order_no from booksmanger.user as u inner join `order` as o on u.id=o.user_id
-
left join 等同于 left outer join:
解释:
无论左表是否匹配到右表,都返回左表的所有行,如左表有1,2,3,右表有2,3,4,则左连接查询结果为:左表 右表 1 null 2 2 3 3 select u.username,o.order_no from booksmanger.user as u left join `order` as o on u.id=o.user_id
select u.username,o.order_no from booksmanger.user as u left outer join `order` as o on u.id=o.user_id
-
right join 等同于 right outer join:
解释:
与left正好相反,无论右表是否匹配到左表,都返回右表的所有行,如左表有1,2,3,右表有2,3,4,则右连接查询结果为:左表 右表 2 2 3 3 null 4 select u.username,o.order_no from booksmanger.user as u right join `order` as o on u.id=o.user_id
select u.username,o.order_no from booksmanger.user as u right outer join `order` as o on u.id=o.user_id
-
full join :
解释:
无论两表是否匹配,都返回两表的所有行:左表 右表 1 null 2 2 3 3 null 4
DISTINCT : 去重
SELECT DISTINCT 列名称 FROM 表名称;
创建索引: CREATE INDEX :
在不读取整个表的情况下,索引使数据库应用程序可以更快地查找数据
CREATE INDEX index_name
ON table_name (column_name)
函数:
GROUP BY 语句
GROUP BY 语句用于结合合计函数,根据一个或多个列对结果集进行分组。
HAVING 子句
在 SQL 中增加 HAVING 子句原因是,WHERE 关键字无法与合计函数一起使用。
例:查找订单总金额少于 2000 的客户:
SELECT Customer,SUM(OrderPrice) FROM Orders
GROUP BY Customer
HAVING SUM(OrderPrice)<2000
find_in_set
类似与in,但in一般用于固定值或通过其它条件查询出来的后的固定值,例如:
select * from user where age in (20,30,60);
查询出年龄在20,30 ,60岁中的用户!
find_in_set则是查询出某个字段中包含有给定值的数据:
例如:
查询字段role中含有2的数据:
select * from user where find_in_set ('2',role);
查询结果:
如果用like 是无法精准匹配的如(1,2,3)和(1,20,3)!
find_in_set一般用于像上表中定义有逗号分割的数据。
视图:
w3c解释:
基于SQL语句结果集的可视化表;
什么意思呢?就拿上面的查询语句及结果举例,在DataGrip中:
查询结果:
这个结果就是基于sql语句的结果集,但它仅仅是在DataGrip或Navicat或其它中数据库管理工具中,输入sql语句,然后点击查询的一个结果反映,就像控制台打印的一个log一样,你仅仅是看到了这条语句的执行结果,没有其它实际意义,执行其它sql语句或关掉工具时它就消失了!
而视图,则可以把这个结果所展现出来的’表’,转化为一个类似于真实的表(你完全可以把它看作一个真实的表),然后你就可以直接像查询真实表一样使用sql语句去查询这个视图,且视图在你主动删除前是一直存在的,操作视图不会影响数据库中的真实数据!
创建视图:
create view user_order as
select u.username,o.order_no from booksmanger.user u,`order` o
where u.id=o.user_id order by o.order_no;
从视图中查询:
select username from user_order;
结果:
结果是一模一样的!
存储过程(Stored Procedure):
是一种在数据库中存储复杂程序,以便外部程序调用的一种数据库对象。
存储过程是为了完成特定功能的SQL语句集,包含逻辑控制语句如 if,end if…,和数据库操作语句(增删改查),经编译创建并保存在数据库中,用户可通过指定存储过程的名字并给定参数(需要时)来调用执行。
存储过程思想上很简单,就是数据库 SQL 语言层面的代码封装与重用,就如我们在开发过程中为一种功能封装了一个公共方法供全局调用一样!
存储过程可封装,并隐藏复杂的商业逻辑,但往往定制化于特定的数据库上,因为支持的编程语言不同。当切换到其他厂商的数据库系统时,需要重写原有的存储过程!
拿上面的user表举一个简单的例子,创建存储过程:
create procedure getUser()
begin
select * from booksmanger.user;
end;
调用存储过程:
call getUser();
是不是跟我们写一个func很像?!
带参数:
1、
create procedure getUserNameById(userId int)
begin
select username from booksmanger.user where id=userId;
end;
call getUserNameById(1);
结果:
2、
create procedure getUsersByRole(_role varchar(50))
begin
select username from booksmanger.user where find_in_set (_role,role);
end;
call getUsersByRole('2');
结果:
DELIMITER :用于向 mysql 提交查询语句,因为MySQL delimiter默认结束符为";",而存储过程中的sql结束符也是“;”,不能每遇到";"就提交一次,所以一般的,需要自定义delimiter的结束符,在创建存储过程开头定义:DELIMITER $$
或 DELIMITER //
,存储过程中有需要提交的地方,就以$$
或//
结尾即可,最后在存储过程末尾恢复默认:DELIMITER
:
delimiter $$
drop procedure if exists getLastOrderByUserId; $$
create procedure getLastOrderByUserId(userId int)
begin
declare orderNo varchar(50);
select order_no into orderNo from `order` where user_id=userId order by id desc limit 1;
select orderNo;
end; $$
delimiter ;
这其中又包含了declare关键字,定义变量,另外还有set关键字,为变量赋值等…,select orderNo相当于返回orderNo!
存储过程的参数有三种定义:
- IN 输入参数:表示调用者向过程传入值(传入值可以是字面量或变量);
- OUT 输出参数:表示过程向调用者传出值(可以返回多个值)(传出值只能是变量);
- INOUT 输入输出参数:既表示调用者向过程传入值,又表示过程向调用者传出值(值只能是变量),建议尽量使用in和out区分输入输出参数,少用inout类型;
in:
delimiter $$
create procedure testIN(in paramIn int)
begin
set paramIn=2;
select paramIn;
end; $$
delimiter ;
set @paramIn=1;
call testIN(@paramIn);
select @paramIn;
结果:call testIN(@paramIn)
输出2,select @paramIn
输出1!
可以看出在参数为传入类型in时,paramIn
在存储过程中被修改,但并不影响 @paramIn
的值,因为前者为局部变量、后者为全局变量!
out:
delimiter $$
create procedure testOut(out paramOut int)
begin
set paramOut=2;
select paramOut;
end; $$
delimiter ;
set @paramOut=1;
call testOut(@paramOut);
select @paramOut;
结果:call testOut(@paramOut)
输出2,select @paramOut
输出2,可以看出,参数为输出类型out时,paramOut在存储过程中发生了改变,这就是与in类型的区别!
以下是DataGrip中创建的视图和存储过程:
以上是关于SQL温故的主要内容,如果未能解决你的问题,请参考以下文章