数据库是用来存储数据,更新,查询数据的工具,而查询数据是一个数据库最为核心的功能,数据库是用来承载信息,而信息是用来分析和查看的。所以掌握更为精细化的查询方式是很有必要的。本文将围绕数据的高级查询语句展开。
为了下面查询语句的运用,事先准备了两张表,后续也会根据查询功能的运用会对表进行一些变动,或创建新表
CREATE TABLE miss (
id int(4) ,
name char(4),
height double
) ;
CREATE TABLE miss2 (
name char(4),
hobby char(10),
date char(10)
) ;
select 字段1,字段2 from 表名;
SELECT DISTINCT "字段" FROM "表名";
SELECT "字段" FROM 表名" WHERE "条件";
SELECT "字段" FROM "表名" WHERE "条件1" AND "条件2";
SELECT "字段" FROM "表名" WHERE "条件1" OR "条件2";
SELECT "字段" FROM "表名" WHERE "字段" IN ('值1', '值2', ...); #in,遍历一个取值列表
SELECT "字段" FROM "表名" WHERE "字段" BETWEEN '值1' AND '值2';
like查询通常会与通配符配合使用
%:百分号表示零个、一一个或多个字符
_:划线表示单个字符
select * from miss where hobby like '%ing';
select * from miss2 where name like '胡_';
select * from miss where name like '_击';
select * from miss2 where hobby like '%ni%';
order by,按关键字排序
注意:
SELECT "字段" FROM "表名" [WHERE "条件"] ORDER BY "字段" [ASC|DESC] ;
#ASC是按照升序进行排序的,是默认的排序方式。
#DESC是按降序方式进行排序。
select * from miss order by height;
select * from miss order by height asc;
select * from miss order by height desc;
数学函数 | 作用 |
abs(x) | 返回x的绝对值 |
rand() | 返回0到1的随机数 |
mod(x, y) | 返回x除以y以后的余数 |
power(x, y) | 返回x的y次方 |
round(x) | 返回离x最近的整数 |
round(x, y) | 保留x的y位小数四舍五入后的值 |
sqrt(x) | 返回x的平方根 |
truncate(x, y) | 返回数字x截断为y位小数的值 #不四舍五入 |
ceil(x) | 返回大于或等于x的最小整数 |
floor(x) | 返回小于或等于x的最大整数 |
greatest(x1,x2,...) | 返回集合中最大的值 |
least(x1,x2,...) | 返回集合中最小的值 |
SELECT abs(-1),rand(), mod(5,3) ,power(2,3);
SELECT truncate(1.89,2);
SELECT truncate(1.89,1);
select ceil(1.76);
select floor(1.76);
select greatest(1,2,3,55,12,55,61);
select least(1,2,3,55,12,55,61);
聚合函数 | 含义 |
avg() | 返回指定列的平均值 |
count() | 返回指定列中非 NULL 值的个数 |
min() | 返回指定列的最小值 |
max() | 返回指定列的最大值 |
sum(字段) | 返回指定列的所有值之和 |
select avg(height) from miss;
select count(name) from miss;
select count(*) from miss;
select max(height) from miss;
select min(height) from miss;
select sum(height) from miss;
SELECT TRIM ([ [位置] [要移除的字符串] FROM ] 字符串);
#[位置]:值可以为 LEADING (起头), TRAILING (结尾), BOTH (起头及结尾)。
#[要移除的字符串]:从字串的起头、结尾,或起头及结尾移除的字符串。缺省时为空格。
select trim(leading 'r' from 'running' );
select trim(trailing 'g' from 'running' );
select trim(both 'l' from 'lol' );
substr(x,y) #截取x字符串 从第y个开始,截取到末尾
substr(x,y,z) #截取x字符串 从第y个开始截取 ,截取长度为z
select substr(hobby,2) from miss2;
select substr(hobby,3) from miss2;
select substr(hobby,2,5) from miss2;
select substr(hobby,4,6) from miss2;
concat(x,y)
select concat(name,height) from miss;
使用 || 符号
#将info表中,name字段值和height字段值拼接在一起。
select name || height from miss;
将miss表中,name字段值和height字段值拼接在一起,且中间加空格。
select name || ' ' || height from miss;
select length(hobby) from miss2;
select replace(name,'反','攻') from miss2;
对GROUPBY后面的字段的查询结果进行汇总分组,通常是结合聚合函数一起使用的
select name, count(name) from miss group by name;
select name,sum(saving) from miss3 group by name;
select name,sum(saving) from miss3 group by name order by sum(saving) desc;
用来过滤由"GROUP BY"语句返回的记录集,通常与"GROUP BY"语句联合使用。
HAVING语句的存在弥补了WHERE 关键字不能与聚合函数联合使用的不足。
where只能对原表中的字段进行筛选,不能对group by后的结果进行筛选。
SELECT 字段1,SUM(字段2) FROM "表格名" GROUP BY 字段1 HAVING(函数条件) ;
select name,sum(saving) from miss3 group by name having sum(saving)>3500;
语法格式:
SELECT 字段1,字段2 AS 字段2的别名 from 表名; #AS可以省略不写
select name,sum(saving) as total_saving from miss3 group by name having sum(saving)>3000;
select name,sum(saving) as total_saving from miss3 group by name having total_saving>3000;
SELECT 表格别名.字段1 [AS] 字段别名 FROM 表格名 [AS] 表格别名; #AS可以省略不写
对下面的表进行saving比较并且进行排名通过表的自我连接进行实现
表的自我连接达到排名的原理分析及操作思路:
1.以上面的数据表为例,假设共有五个人,他们手中的金额各不相同。我们已经进行表的自我连接。
2. 使用count计数,只计数大于等于自身手上金额的人数,比如3000的声望,大于等于她的人数只有2个,就计数值也可以当作她的排名
3.再比如900的无比,大于等于她的有5个人,就该计数值为5,同理可以证明她排名第五。
select A.name,A.saving,count(A.saving) as rank from miss3 as A,info3 as B where A.saving <=B.saving group by A.name,A.saving order by rank asc;
表插入数据
select A.name,A.saving,count(A.saving) as rank from miss3 as A,miss3 as B where A.saving < B.saving or (A.name=B.name and A.saving=B.saving) group by A.name,A.saving order by rank asc;
子查询:连接表格,在WHERE 子句或HAVING 子句中插入另一个SQL语句。
SELECT "字段1" FROM "表格1" WHERE "字段2" [比较运算符] #外查询
(SELECT "字段1" FROM "表格2" WHERE "条件") ; #内查询
select * from miss as A, miss3 as B where A.name=B.name;
select * from miss where name in(select name from miss3 where saving > 2000);
求“英伦地区”的所有saving值之和
select sum(saving) from miss3 where name in (select name from miss where address='英伦');
MYSQL数据库中常用的表连接有三种:
select * from miss A inner join miss3 B on A.name = B.name;
select * from miss A, miss3 B where A.name=B.name;
select * from miss A inner join miss3 B using(name);
select * from miss A LEFT JOIN miss3 B on A.name=B.name;
select * from miss3 A right join miss B on A.name=B.name ;
视图:可以被当作是虚拟表或存储查询。
CREATE VIEW "视图表名" AS "SELECT 语句"; #创建视图表
DROP VIEW "视图表名"; #删除视图表
创建需求:独立创建一个视图,用来统计info和info3 两张表之间,先对name进行address的汇总,再计算地区的saving之和 。要求体现出address 和sum(sving) 两个字段
create view v_address_saving as select A.address,sum(B.saving) total_saving from miss A inner join miss3 B on A.name=B.name group by address;
视图创建的数据验证:
视图的好处:创建视图的过程虽然和高级查询语句(通过两个select语句进行组合条件划分生成派生表)一样,过程是复杂的,但是如果该查询操作是需要经常使用的,创建视图就很有必要,不仅能简化查询过程,还能对该查询进行进一步操作,而且十分简便。
进一步需求: 需要计算出苏州和上海两个地区的saving之和
select sum(total_saving) as yinglun_ribuluo_saving from v_address_saving where address='英伦'or address='日不落';
视图能否插入数据,要看情况而定:
1)如果视图表是两个表的连接查询(比如视图的A字段来自A表,B字段来自B表,数据是无法插入的)。因为表结构和原表不一致。视图中的字段是根据原表中某个字段,通过函数运算,产生的新字段,而没有真正能够存储的字段,所以该数据是无法插入的。
2)如果视图表结构与原表保持一致,数据是可以插入的,插入的数据是存储在原表中,视图所更新出的数据,其实是映射原表的数据。
show create view 分析创建视图的过程:
UNION联集:将两个SQL语句的结果合并起来,两个SQL语句所产生的字段需要是同样的数据记录种类。
生成结果的数据记录值将没有重复,且按照字段的顺序进行排序。#合并后去重
格式:[select 语句1] UNION [select 语句2];
select name from miss union select name from miss3;
select name from miss union all select name from miss3;
create view v_miss as select distinct name from miss union all select distinct name from miss3;
select name,count(*) from v_miss group by name;
select name from v_miss group by name having count(*) >1;
select A.name from miss A inner join miss3 B on A.name=B.name;
select A.name from miss A inner join miss3 B using(name);
select distinct A.name from miss A inner join miss3 B using(name);
select * from miss A left join miss3 B using(name);
select distinct A.name from miss A left join miss3 B using(name) where B.name is not null;
#使用右连接查出store_name字段的交集值,之后去重
select * from miss A right join miss3 B using(name);
select distinct A.name from miss A right join miss3 B using(name) where A.name is not null;
或
select distinct A.name from miss A right join miss3 B on A.name=B.name where A.name is not null;
select distinct name from miss where name in (select name from miss3);
(1)联级方法中 count(*)<=1
(2)左右内连接 将is not null 改为 is null
(3)子查询 外连接查询 not in (内连接查询)
SELECT CASE ("字段名")
WHEN "条件1" THEN "结果1"
WHEN "条件2" THEN "结果2"
[ELSE "结果N"]
END
FROM "表名";
# "条件"可以是一个数值或是公式。ELSE子句则并不是必须的。
mysql> select address,case address
-> when '无比' then height-10
-> when 胡德' then height+5
-> else height+10
-> end
-> "new_height",name
-> from miss;
格式:
select "字段" from "表名" where "字段" regexp '正则表达式';