Mysql高级(进阶)sql语句(2)

2021年09月16日 阅读数:4
这篇文章主要向大家介绍Mysql高级(进阶)sql语句(2),主要内容包括基础应用、实用技巧、原理机制等方面,希望对大家有所帮助。

Mysql高级(进阶)sql语句

 

 

 

 

 

             1、链接查询正则表达式

             2、CREATE VIEW 视图sql

             3、MySQL之联集、交集值、无交集值、case数据库

             4、排序服务器

             5、空值(NULL) 和 无值(' ') 的区别网络

             6、MySQL之正则表达式架构

             7、存储过程app

 

 

 

 

 

 

 

1、链接查询

location表格不变,将Store_Info这个表修改下优化

UPDATE Store_Info SET store_name='Washington' WHERE sales=300;

例:spa

一、inner join(等值相连):只返回两个表中联结字段相等的行3d

SELECT * FROM localtion A INNER JOIN Store_Info B on A.Store_Name = B.Store_Name;

例:

 

二、left join(左联接):返回包括左表中的全部记录和右表中联结字段相等的记录

SELECT * FROM localtion A left JOIN Store_Info B on A.Store_Name = B.Store_Name;

例:

三、right join(右联接):返回包括右表中的全部记录和左表中联结字段相等的记录

SELECT * FROM localtion A RIGHT JOIN Store_Info B on A.Store_Name = B.Store_Name;

例:

select A.Region REGION, sum(B.sales) from localtion A, Store_Info B where A.store_name = B.store_name group by A.Region;

例:

2、CREATE VIEW 视图

视图跟表格的不一样是,表格中有实际储存资料,而视图是创建在表格之上的一个架构,它自己并不实际储存资料。

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

视图不含有数据,只存储它的定义,它的用途通常能够简化复杂的查询。好比你要对几个表进行链接查询,并且还要进行统计排序等操做,写SQL语句会很麻烦的,用视图将几个表联结起来,而后对这个视图进行查询操做,就和对一个表查询同样,很方便。

语法:CREATE VIEW "视图表名" AS "SELECT 语句";
CREATE VIEW V_REGION_SALES AS SELECT A.Region REGION,SUM(B.Sales) SALES FROM localtion A 
INNER JOIN Store_Info B ON A.Store_Name = B.Store_Name GROUP BY REGION;

SELECT * FROM V_REGION_SALES;
DROP VIEW V_REGION_SALES;

例:

 

3、MySQL之联集、交集值、无交集值、case

一、联集,将两个SQL语句的结果合并起来,两个SQL语句所产生的栏位须要是一样的资料种类
UNION:

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

SELECT Store_Name FROM localtion UNION SELECT Store_Name FROM Store_Info;

例:

UNION ALL

UNION ALL :将生成结果的资料值都列出来,不管有无重复
语法:[SELECT 语句 1] UNION ALL [SELECT 语句 2];

SELECT Store_Name FROM localtion UNION ALL SELECT Store_Name FROM Store_Info;

例:

二、交集值:取两个SQL语句结果的交集

SELECT A.Store_Name FROM localtion A INNER JOIN Store_Info B ON A.Store_Name = B.Store_Name;

SELECT A.Store_Name FROM localtion A INNER JOIN Store_Info B USING(Store_Name);

例:

两表其中一个表没有指定的行,而另外一个表这个行有重复不适用,要求两个表确实有交集的行的时候用没用

SELECT A.Store_Name FROM 
(SELECT Store_Name FROM localtion UNION ALL SELECT Store_Name FROM Store_Info) A 
GROUP BY A.Store_Name HAVING COUNT(*) > 1;

例:

取两个SQL语句结果的交集,且没有重复

SELECT A.Store_Name FROM (SELECT B.Store_Name FROM localtion B INNER JOIN Store_Info C ON B.Store_Name = C.Store_Name) A 
GROUP BY A.Store_Name;

SELECT DISTINCT A.Store_Name FROM localtion A INNER JOIN Store_Info B USING(Store_Name);

SELECT DISTINCT Store_Name FROM localtion WHERE (Store_Name) IN (SELECT Store_Name FROM Store_Info);

SELECT DISTINCT A.Store_Name FROM localtion A 
LEFT JOIN Store_Info B USING(Store_Name) WHERE B.Store_Name IS NOT NULL;

例:

四种去交集且没有重复的方法

 

 

三、无交集值:显示第一个SQL语句的结果,且与第二个SQL语句没有交集的结果,且没有重复

SELECT DISTINCT Store_Name FROM localtion WHERE (Store_Name) NOT IN (SELECT Store_Name FROM Store_Info);

SELECT DISTINCT A.Store_Name FROM localtion A 
LEFT JOIN Store_Info B USING(Store_Name) WHERE B.Store_Name IS NULL;

例:

create view V_Store_Name as select distinct store_name from localtion UNION ALL select distinct store_name from Store_Info;

select * from V_Store_Name;

select store_name from V_Store_Name group by store_name having count(store_name) = 1;

select store_name,count(store_name) from V_Store_Name group by store_name;

select store_name,count(store_name) from V_Store_Name group by store_name having count(store_name) =1;

例:

 

四、CASE:是 SQL 用来作为 IF-THEN-ELSE 之类逻辑的关键字

语法:
SELECT CASE ("栏位名")
  WHEN "条件1" THEN "结果1"
  WHEN "条件2" THEN "结果2"
  ...
  [ELSE "结果N"]
  END
FROM "表名";

# "条件" 能够是一个数值或是公式。 ELSE 子句则并非必须的。

SELECT Store_Name, CASE Store_Name 
  WHEN 'Los Angeles' THEN Sales * 2 
  WHEN 'Boston' THEN Sales * 1.5 
  ELSE Sales 
  END 
"New Sales",Date 
FROM Store_Info;

#"New Sales" 是用于 CASE 那个栏位的栏位名。

例:

4、排序

在排序前先准备下用来实验的表格

CREATE TABLE Total_Sales (Name char(10),Sales int(5));
INSERT INTO Total_Sales VALUES ('xiaoming',10);
INSERT INTO Total_Sales VALUES ('xiaogang',15);
INSERT INTO Total_Sales VALUES ('xiaoqiang',20);
INSERT INTO Total_Sales VALUES ('xiaohong',40);
INSERT INTO Total_Sales VALUES ('xiaoliu',50);
INSERT INTO Total_Sales VALUES ('xiaozhang',20);
INSERT INTO Total_Sales VALUES ('xiaoli',30);

例:

一、算排名表格自我连结 (Self Join),而后将结果依序列出,算出每一行以前 (包含那一行自己) 有多少行数

SELECT A1.Name, A1.Sales, COUNT(A2.Sales) Rank FROM Total_Sales A1, Total_Sales A2 
WHERE A1.Sales < A2.Sales OR (A1.Sales=A2.Sales AND A1.Name = A2.Name) 
GROUP BY A1.Name, A1.Sales ORDER BY A1.Sales DESC;

例:

统计Sales栏位的值是比本身自己的值小的以及Sales栏位和Name栏位都相同的数量,好比xiaoming为6+1=7

二、算中位数

SELECT Sales Middle FROM (SELECT A1.Name,A1.Sales,COUNT(A2.Sales) Rank FROM Total_Sales A1,Total_Sales A2 
WHERE A1.Sales < A2.Sales OR (A1.Sales=A2.Sales AND A1.Name <= A2.Name) 
GROUP BY A1.Name, A1.Sales ORDER BY A1.Sales DESC) A3 
WHERE A3.Rank = (SELECT (COUNT(*)+1) DIV 2 FROM Total_Sales);

例:

每一个派生表必须有本身的别名,因此别名 A3 必需要有
DIV 是在 MySQL 中算出商的方式
三、算累积总计表格自我连结 (Self Join),而后将结果依序列出,算出每一行以前 (包含那一行自己) 的总合

SELECT A1.Name, A1.Sales, SUM(A2.Sales) Sum_Total FROM Total_Sales A1, Total_Sales A2 
WHERE A1.Sales < A2.Sales OR (A1.Sales=A2.Sales AND A1.Name = A2.Name) 
GROUP BY A1.Name, A1.Sales ORDER BY A1.Sales DESC;

例:

四、算总合百分比

SELECT A1.Name, A1.Sales, A1.Sales/(SELECT SUM(Sales) FROM Total_Sales) Per_Total 
FROM Total_Sales A1, Total_Sales A2 
WHERE A1.Sales < A2.Sales OR (A1.Sales=A2.Sales AND A1.Name = A2.Name) 
GROUP BY A1.Name, A1.Sales ORDER BY A1.Sales DESC;

#SELECT SUM(Sales) FROM Total_Sales 这一段子查询是用来算出总合
#总合算出后,咱们就可以将每一行一一除以总合来求出每一行的总合百分比

例:

五、算累积总合百分比

SELECT A1.Name, A1.Sales, SUM(A2.Sales)/(SELECT SUM(Sales) FROM Total_Sales) Per_Total 
FROM Total_Sales A1, Total_Sales A2 
WHERE A1.Sales < A2.Sales OR (A1.Sales=A2.Sales and A1.Name = A2.Name) 
GROUP BY A1.Name, A1.Sales ORDER BY A1.Sales DESC;

例:

用累积总计 SUM(a2.Sales) 除以总合来求出每一行的累积总合百分比

SELECT A1.Name, A1.Sales, TRUNCATE(ROUND(SUM(A2.Sales)/(SELECT SUM(Sales) FROM Total_Sales),4)*100,2) || '%' Per_Total 
FROM Total_Sales A1, Total_Sales A2 
WHERE A1.Sales < A2.Sales OR (A1.Sales=A2.Sales and A1.Name = A2.Name) 
GROUP BY A1.Name, A1.Sales ORDER BY A1.Sales DESC;

例:

这里建议你们若是以为SQL语句有点长,你们能够采用视图的方法

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

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

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

3.无值的判断使用=''或者<>''来处理。<> 表明不等于。

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

SELECT length(NULL), length(''), length('1');
SELECT * FROM city WHERE name IS NULL;
SELECT * FROM city WHERE name IS NOT NULL;
SELECT * FROM city WHERE name = '';
SELECT * FROM city WHERE name <> '';
SELECT COUNT(*) FROM city;
SELECT COUNT(name) FROM city;

例:

6、MySQL之正则表达式

匹配模式			描述					实例
^ 			匹配文本的开始字符 		     ‘^bd’ 匹配以 bd 开头的字符串
$ 			匹配文本的结束字符 		     ‘qn$’ 匹配以 qn 结尾的字符串
. 			匹配任何单个字符			     ‘s.t’ 匹配任何 s 和 t 之间有一个字符的字符串
* 			匹配零个或多个在它前面的字符 	     ‘fo*t’ 匹配 t 前面有任意个 o
+ 			匹配前面的字符 1 次或屡次		     ‘hom+’ 匹配以 ho 开头,后面至少一个m 的字符串
字符串 			匹配包含指定的字符串 			‘clo’ 匹配含有 clo 的字符串
p1|p2 			匹配 p1 或 p2 				‘bg|fg’ 匹配 bg 或者 fg
[...] 			匹配字符集合中的任意一个字符 		‘[abc]’ 匹配 a 或者 b 或者 c
[^...] 			匹配不在括号中的任何字符 			‘[^ab]’ 匹配不包含 a 或者 b 的字符串
{n} 			匹配前面的字符串 n 次 			‘g{2}’ 匹配含有 2 个 g 的字符串
{n,m}			匹配前面的字符串至少 n 次,至多m 次		‘f{1,3}’ 匹配 f 最少 1 次,最多 3 次

语法格式:

语法:SELECT "栏位" FROM "表名" WHERE "栏位" REGEXP {模式};
SELECT * FROM Store_Info WHERE Store_Name REGEXP 'os';
SELECT * FROM Store_Info WHERE Store_Name REGEXP '^[A-G]';
SELECT * FROM Store_Info WHERE Store_Name REGEXP 'Ho|Bo';

例:

7、存储过程

一、存储过程是一组为了完成特定功能的SQL语句集合。

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

三、存储过程的优势:

(1)执行一次后,会将生成的二进制代码驻留缓冲区,提升执行效率

(2)SQL语句加上控制语句的集合,灵活性高

(3)在服务器端存储,客户端调用时,下降网络负载

(4)可屡次重复被调用,可随时修改,不影响客户端调用

(5)可完成全部的数据库操做,也可控制数据库的信息访问权限

四、建立存储过程

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

五、调用存储过程

CALL Proc;

例:

六、查看存储过程

SHOW CREATE PROCEDURE [数据库.]存储过程名;		#查看某个存储过程的具体信息

SHOW CREATE PROCEDURE Proc;

SHOW PROCEDURE STATUS [LIKE '%Proc%'] \G

七、存储过程的参数

IN 输入参数:表示调用者向过程传入值(传入值能够是字面量或变量)
OUT 输出参数:表示过程向调用者传出值(能够返回多个值)(传出值只能是变量)
INOUT 输入输出参数:既表示调用者向过程传入值,又表示过程向调用者传出值(值只能是变量)

DELIMITER $$				
CREATE PROCEDURE Proc1(IN inname CHAR(16))		
-> BEGIN					
-> SELECT * FROM Store_Info WHERE Store_Name = inname;
-> END $$					
DELIMITER ;					

CALL Proc1('Boston');

例:

八、删除存储过程
存储过程内容的修改方法是经过删除原有存储过程,以后再以相同的名称建立新的存储过程。

DROP PROCEDURE IF EXISTS Proc;

仅当存在时删除,若是指定的过程不存在,会产生一个错误

例:

九、存储过程的控制语句

create table t (id int(10));
insert into t values(10);

(1)条件语句if-then-else-end if

DELIMITER $$  
CREATE PROCEDURE proc2(IN parameter int)  
-> begin 
-> declare var int;  
-> set var=parameter*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);

例:

 

 

(2)循环语句while ···· end while

DELIMITER $$  
CREATE PROCEDURE proc3()
-> begin 
-> declare var int(10);  
-> set var=0;  
-> while var<6 do  
-> insert into t values(var);  
-> set var=var+1;  
-> end while;  
-> end $$  

DELIMITER ;

CALL Proc3;

例: