MySQL高级语句(二)

目录

一、 CREATE VIEW(视图)

  二、联集

2.1UNION

 2.2UNION ALL

 三、交集值

​编辑

四、无交集值

五、CASE

 六、空值(NULL) 和 无值(’ ') 的区别

七、正则表达式

八、存储过程

8.1 存储过程的优点 

8.2 创建存储过程 

8.3 调用存储过程

8.4 查看存储过程

8.5 存储过程的参数

8.6 删除存储过程

8.7 存储过程的控制语句


一、 CREATE VIEW(视图)

可以被当作是虚拟表或存储查询

(1)视图跟表格的不同是,表格中有实际储存资料,而视图是建立在表格之上的一个架构,它本身并不实际储存资料。

(2)临时表在用户退出或同数据库的连接断开后就自动消失了,而视图不会消失。

(3)视图不含有数据,只存储它的定义,它的用途一般可以简化复杂的查询。比如你要对几个表进行连接查询,而且还要进行统计排序等操作,写SQL语句会很麻烦的,用视图将几个表联结起来,然后对这个视图进行查询操作,就和对一个表查询一样,很方便。

#语法:
CREATE VIEW "视图表名" AS "SELECT 语句";

简单来说,就是把select查询的语句保存起来。但保存的结果并不是固定的,select语句的结果如果发生了变化,保存的结果也会随之改变。

面试题:视图表中能否插入数据?

答:依情况而定。若视图表与原表结构发生了改变,就不能被插入或修改。他也可以插入数据,就看 视图表的定义结构与原表结构是否一样。

 视图表保存着select语句执行的结果,视图表相当于select语句的别名。。

方便后面对select语句再次操作。


派生表:把查询结果当成一个表去看待。(子查询是查询的一个字段的结果)

 将该select语句作为派生表:

 此时,C就是select语句的派生表。

语句太长,拆分为两端:

之前创建了V_REGION_SALES的视图表。

 直接对视图表进行操作即可。 

视图表保存着select语句执行的结果,视图表相当于select语句的别名。

可以让select语句后续操作简化。

面试题:视图表中能否插入数据?

答:依情况而定。若视图表与原表结构发生了改变,就不能被插入或修改。他也可以插入数据,就看 视图表的定义结构与原表结构是否一样。

例: 

 我们去修改该视图表:

 查看实际表,也被修改了。

 表结构改变后,就不可以修改内容了。

  二、联集

  • 联集,将两个SQL语句的结果合并起来,两个SQL语句所产生的栏位需要是同样的资料种类

  • 2.1UNION

  • 生成结果的资料值将没有重复,且按照字段的顺序进行排序
#语法:
[SELECT 语句 1] UNION [SELECT 语句 2];

 2.2UNION ALL

将生成结果的资料值都列出来,无论有无重复


UNIONALL:将生成结果的数据记录值都列出来,无论有无重复
语法: [SELECT 语句1] UNION ALL [SELECT 语句2] ;
​
举例:
------------------
select store_name from location union select store_name from store_info;
select store_name from location union all select store_name from store_info;

 三、交集值

取两个SQL语句结果的交集

---- 交集值----取两个sQL语句结果的交集
SELECT A.Store_ Name FROM location A INNER JOIN Store_ Info B ON A.Store_ Name = B.Store_ Name ; 
SELECT A.Store_ Name FROM location A INNER JOIN Store_ Info B USING(Store_ Name) ;
​
#取两个sQL语句结果的交集,且没有重复
SELECT DISTINCT A.Store_ Name FROM location A INNER JOIN Store_ Info B USING (Store_ Name) ;
SELECT DISTINCT Store_ Name FROM location WHERE (Store_ Name) IN (SELECT Store_ Name FROM Store_ Info);
SELECT DISTINCT A.Store_ Name FROM location A LEFT JOIN Store_ Info B USING(Store_ Name) WHERE B.Store_ Name IS NOT NULL;
SELECT A.Store_ Name FROM (SELECT B.Store_ Name FROM location B INNER JOIN Store_ Info C ON B.Store_ Name = C.Store_ Name) A
GROUP BY A. Store_ Name;

 

 两个store_name求交集值:

法一:

法二:

 法三:(using)(要保证两个表字段是同名)

 此时,给表store_info插入一个字段:

 

此时用using发现多了一条记录: 

 

用on也多了一条记录:

 用where也多了一条记录:

 可以通过distinct去重:

 除了通过内连接以外,求交集还有其他方法:

1.用左连接的方法求交集

先查询,发现左表中的字段都列了出来,但左表中有一行记录是没有交集的,此时右表的值为null

 用where将右表的null值过滤掉:

 2.用右连接的方法求交集:

 3.in方法

把store_info这张表中的store_name这个列的值查询出来,作为一个取值列表给location这个表去查询,作为他查询的条件,

4.  通过子查询的方法去个重

 5.通过group by:

 再对其进行分组, 在用count 统计,若有重复,则是有交集的,没有重复,则为1,

group by A.Store_Name Having count(*)>1;

这边比较难理解,我们可以先创建一个视图表:

 

 

 再对这个视图表进行分组,

 再通过count进行过滤,把出现2次的过滤出来:

 

 再把count删去,达到求交集的目的:

四、无交集值

法一:通过count进行过滤,把出现1次的过滤出来:

 法二:通过not in只能过滤单边的,再进行合并,即可过滤出双边的无交集值:

 

 法三:通过单边过滤null,再合并

 

 not in和null 只能求出单边无交集值,要想一步到位,只能用法一,求出现次数。

五、CASE

CASE是 SQL 用来做为 IF-THEN-ELSE 之类逻辑的关键字

#语法:
SELECT CASE ("栏位名")
  WHEN "条件1" THEN "结果1"
  WHEN "条件2" THEN "结果2"
  ...
  [ELSE "结果N"]
  END
FROM "表名";
 
# "条件" 可以是一个数值或是公式。 ELSE 子句则并不是必须的。

 

 原表不改变。

 

 六、空值(NULL) 和 无值(’ ') 的区别

(1)无值的长度为 0,不占用空间的;而 NULL 值的长度是 NULL,是占用空间的。

(2)IS NULL 或者 IS NOT NULL,是用来判断字段是不是为 NULL 或者不是 NULL,不能查出是不是无值的。

(3)无值的判断使用=’‘或者<>’'来处理。<> 代表不等于。

(4)在通过 count()指定字段统计有多少行数时,如果遇到 NULL 值会自动忽略掉,遇到无值会加入到记录中进行计算。
 

#示例2:查看空值和非空值
select * from info where name = '';
select * from info where name <> '';

 

 

 查看空值,发现有两个空值。

 

#示例3:统计行数
select COUNT(*) from info;
select COUNT(name) from info;

 

 

七、正则表达式

---- 正则表达式----
匹配模式                  描述
^                   匹配文本的开始字符
$                   匹配文本的结束字符
.                   匹配任何单个字符
*                   匹配零个或多个在它前面的字符
+                   匹配前面的字符1次或多次
字符串               匹配包含指定的字符串
p1|p2               匹配p1或p2
[...]               匹配字符集合中的任意一个字符
[^...]              匹配不在括号中的任何字符
{n}                 匹配前面的字符串n次
{n,m}               匹配前面的字符串至少n次,至多m次
 
 
语法:SELECT  "字段" FROM "表名”WHERE "字段" REGEXP {模式};
SELECT * FROM Store_ Info WHERE Store_ Name REGEXP 'os' ;
SELECT * FROM Store_ Info WHERE Store_ Name REGEXP I^[A-G] ' ;
SELECT * FROM Store_ Info WHERE Store_ Name REGEXP 'Ho | Bo' ; 

#语法:
SELECT "栏位”FROM "表名" WHERE "栏位”REGEXP {模式};
#示例1:查看数据表中的name字段
select name from students;
#示例2:返回表中name中字符带'ua'的数据的全部字段
select * from students where name regexp 'ua';
#示例3:返回表中字段中以'A-G'开头的数据,不区分大小写
select * from students where name regexp '^[A-G]';
#示例4:返回表中字段中以'du'和'hu'开头的全部信息
select * from students where name regexp '^(du|hu)';

八、存储过程

  存储过程是一组为了完成特定功能的SQL语句集合。
  存储过程在使用过程中是将常用或者复杂的工作预先使用SQL语句写好并用一个指定的名称存储起来,这个过程经编译和优化后存储在数据库服务器中。
  当需要使用该存储过程时,只需要调用它即可。存储过程在执行上比传统SQL速度更快、执行效率更高。

 

8.1 存储过程的优点 

封装性

通常完成一个逻辑功能需要多条 SQL 语句,而且各个语句之间很可能传递参数,所以,编写逻辑功能相对来说稍微复杂些,而存储过程可以把这些 SQL 语句包含到一个独立的单元中,使外界看不到复杂的 SQL 语句,只需要简单调用即可达到目的。并且数据库专业人员可以随时对存储过程进行修改,而不会影响到调用它的应用程序源代码

可增强 SQL 语句的功能和灵活性

存储过程可以用流程控制语句编写,有很强的灵活性,可以完成复杂的判断和较复杂的运算。

可减少网络流量

由于存储过程是在服务器端运行的,且执行速度快,因此当客户计算机上调用该存储过程时,网络中传送的只是该调用语句,从而可降低网络负载。

提高性能

当存储过程被成功编译后,就存储在数据库服务器里了,以后客户端可以直接调用,这样所有的 SQL 语句将从服务器执行,从而提高性能。但需要说明的是,存储过程不是越多越好,过多的使用存储过程反而影响系统性能

提高数据库的安全性和数据的完整性

存储过程提高安全性的一个方案就是把它作为中间组件,存储过程里可以对某些表做相关操作,然后存储过程作为接口提供给外部程序。这样,外部程序无法直接操作数据库表,只能通过存储过程来操作对应的表,因此在一定程度上,安全性是可以得到提高的。

使数据独立

数据的独立可以达到解耦的效果,也就是说,程序可以调用存储过程,来替代执行多条的 SQL 语句。这种情况下,存储过程把数据同用户隔离开来,优点就是当数据表的结构改变时,调用表不用修改程序,只需要数据库管理者重新编写存储过程即可。

8.2 创建存储过程 

DELIMITER $$                      #将语句的结束符号从分号;临时改为两个$$(可以是自定义)
CREATE PROCEDURE Proc()           #创建存储过程,过程名为Proc,不带参数
> BEGIN                           #过程体以关键字BEGIN开始
-> select * from Store_ Info;     #过程体语句
-> END $$                         #过程体以关键字END结束
DELIMITER ;                       #将语句的结束符号恢复为分号;

语法说明如下:
$$ 是用户定义的结束符,通常这个符号可以是一些特殊的符号,如两个“?”或两个“¥”等。
当使用 DELIMITER 命令时,应该避免使用反斜杠“\”字符,因为它是 MySQL 的转义字符
 
成功执行这条 SQL 语句后,任何命令、语句或程序的结束标志就换为两个??
mysql > DELIMITER ??
若希望换回默认的分号“;”作为结束标志,则在 MySQL 命令行客户端输入下列语句即可
mysql > DELIMITER ;
注意:DELIMITER 和分号“;”之间一定要有一个空格 

 示例:

delimiter $$					#将语句的结束符号从分号;临时改为两个$$ (可以是自定义)
create procedure proc5()        #创建存储过程,过程名为proc, 不带参数
-> begin                        #过程体以关键字BEGIN开始
-> select * from students;      #过程体语句(自己根据需求进行编写)
-> end $$						#过程体以关键字END结束
delimiter ;                     #将语句的结束符号恢复为分号

8.3 调用存储过程

call proc;

8.4 查看存储过程

SHOW CREATE PROCEDURE [ 数据库. ]存储过程名;
#查看某个存储过程的具体信息
​
SHOW CREATE PROCEDURE Proc;
SHOW PROCEDURE STATUS [LIKE ' 8Proc8' ] \G

8.5 存储过程的参数

IN输入参数:表示调用者向过程传入值(传入值可以是字面量或变量)
OUT输出参数:表示过程向调用者传出值(可以返回多个值) (传出值只能是变量)
INOUT输入输出参数:既表示调用者向过程传入值,又表示过程向调用者传出值(值只能是变量)
#示例:
delimiter $$                                                                        
create procedure proc11(in inname char(40))
-> begin
-> select * from students where name = inname;
-> end $$                                                                              
mysql> delimiter ;
call proc11('Xi Ren');

 

8.6 删除存储过程

存储过程内容的修改方法是通过删除原有存储过程,之后再以相同的名称创建新的存储过程。
DROP PROCEDURE IF EXISTS Proc;
#仅当存在时删除,不添加IF EXISTS 时,如果指定的过程不存在,则产生一个错误

8.7 存储过程的控制语句

条件语句:if-then-else .... end if 

DELIMITER $$
CREATE PROCEDURE proc2 (IN pro int)
-> begin
-> declare var int ;
-> set var=pro*2;
if var>=10 then
-> update t set id=id+1;
-> else
-> update t set id=id-1;
-> end if;
-> end $$;
​
DELIMITER ;
​
CALL Proc2 (6) ;

 while......end while

DELIMITER $$                                            #修改默认结束符为$$
-> create procedure yxp()                           #创建存储过程yxp
-> begin                                                #过程体以关键字begin开始
-> declare i int;                               #定义变量i为int类型(长度最大为10)
-> set i = 1;                                           #设置i = 1;
->  while i <= 100                                  #使用while循环,i要小于100
-> do insert into nametest(name,age) values
            #满足条件则进行添加数据,内容为变量i
-> set i=i+1;                                       #变量i每次循环后加1                             
-> end while;                                           #结束while循环
-> end $$                                               #创建存储过程结束
delimiter ;                                             #重新修改默认结束符为原始的;
CALL proc6;                                             #调用yxp存储过程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值