MySQL数据库 | 数据表-查询命令详细记录
本篇专门记录数据库增删改查中最常用、花招最多的 查。
【文章结构】
一、数据的准备
二、基本的查询功能
三、条件查询
四、查询排序
五、聚合函数
六、分组查询
七、分页查询
八、连接查询
九、子查询
十、自关联
【正文】
一、数据的准备
首先创建一个数据库,以便后文命令的使用。
注意,我使用高版本时,发现groups 不能用作表名了
-- 创建一个数据库 create database pysql charset=utf8; -- 使用数据库 use pysql; -- 查看当前使用的是哪个数据库 select database(); -- 创建数据表groups, heroes create table groups ( id int unsigned auto_increment primary key, name varchar(20) not null ); create table heroes ( id int unsigned auto_increment primary key not null, name varchar(20) default "", age tinyint unsigned default 0, height decimal(5,2), gender enum("男", "女", "保密") default "保密", grp_id int unsigned default 0, is_delete bit default 0 ); -- 查看数据库中已有的数据表 show tables; -- 了解数据表的创建方式 show create table heroes; -- 插入数据 insert into heroes values (0,"妮蔻",18,150.00,2,1,0), (0,"泰隆",50,188.00,1,1,0), (0,"阿狸",16,179.00,1,1,0), (0,"赏金",17,175.68,2,3,1), (0,"盲僧",90,190.00,1,1,0), (0,"盖伦",30,197.89,1,1,0), (0,"光辉",18,160.00,2,1,1), (0,"希维尔",21,167.90,3,2,0), (0,"劫",70,null,2,1,1), (0,"派克",34,170.00,1,6,0), (0,"卡莎",18,180.90,2,1,0), (0,"塔姆",56,150.00,1,2,0), (0,"阿木木",90,130.01,1,1,0), (0,"娜美",18,173.00,2,4,0); insert into groups values (0, "宗师"), (0, "黑铁"), (0, "黄金");
二、基本的查询功能
-- 查询所有字段(大数据库中慎用) -- select * from 表名; select * from heroes; select * from groups; -- 查询指定字段 -- select 列1, 列2,...from 表名; select name, age from heroes; -- 使用as给字段起别名 -- select 字段 as 别名 from 表名; select name as "姓名", age as "年龄" from heroes; -- select 表名.字段... from 表名 select heroes.name, heroes.gender from heroes; -- 通过as给表起别名 select h.name, h.gender from heroes as h; -- select heroes.name, heroes.gender from heroes as h; 报错,改了名就要用... -- 消除重复行(要是京东查手机的时候能有这么个命令,出现过的型号不要再出现就好了) -- distinct 字段 select distinct gender from heroes;
三、条件查询
-- 比较运算符 -- select ... from 表名 where 条件 -- > -- 查询大于18岁的信息 select * from heroes where age>18; -- < -- 查询id小于5的信息 select * from heroes where id<5; -- >= -- <= -- 略 -- = --查询性别为男的英雄的id和名字 select id,name from heroes where gender=1; -- != 或者 <> (<>在很多语言中都不用,所以首选 !=) select id,name from heroes where gender!=1; -- 逻辑运算符(与 或 非) -- and -- 18到50岁之间英雄的信息 -- 报错 select * from heroes where age>18 and <50; 判断语句 左右两边都要写全 select * from heroes where age>18 and age<50; -- 18岁以上的女性 select * from heroes where age>18 and gender=2; select * from heroes where age>18 and gender="女"; -- or -- 50岁以上或身高180(包含)以上 select * from heroes where age>50 or height>=180; -- not -- not 加在谁前面就仅仅否定这一个条件,用()解决优先级的问题,不要死记硬背 -- 不属于 70岁以上男英雄 的 select * from heroes where not (age>70 and gender=1); -- 年龄不小于或等于18 的女性英雄.用()解决优先级的问题 select * from heroes where (not age<=18) and gender=2; -- 模糊查询 -- like (效率低) -- % 替换1个,0个或多个 -- _替换一个 --查询姓名中以“赏”开头的名字 select name from heroes where name like "赏%"; --查询姓名中有“赏”的名字 select name from heroes where name like "%赏%"; --查询两个字的名字 select name from heroes where name like "__"; --查询至少两个字的名字 select name from heroes where name like "__%"; -- rlike 正则 -- 查询以“泰”开始的名字 select name from heroes where name rlike "^泰.*"; -- 查询以“希”开头,“尔”结尾的名字 select name from heroes where name rlike "^希.*尔$"; -- 范围查询 -- in (18, 70, 50) 表示在一个非连续的范围内 -- 查询年龄为18,70的英雄 select name, age from heroes where age in (18, 70, 50); -- not in (18, 70, 50) 不在某个非连续的范围内 select name, age from heroes where age not in (18, 70, 50); -- between .. and .. 在某个连续的范围内 select name, age from heroes where age between 18 and 50; -- not between .. and .. 不在某个范围中,这是一个整体的语句,同时否定between和and的内容 -- 报错 select name, age from heroes where age not (between 18 and 50); select name, age from heroes where age not between 18 and 50; select name, age from heroes where not age between 18 and 50; -- 判断为空 -- is null -- a = None 表示 a没有指向任何东西,a = "" 表示a指向一个为空的对象 -- 查询身高为空的信息 select * from heroes where height is null; -- 不为空的 select * from heroes where height is not null;
四、查询排序
-- order by 字段 -- asc 升序(默认值) -- desc 降序 -- 先写那个条件,先按照这个条件排序,相同情况下,按第二个排,否则不生效 --查询年龄在20-70的男英雄,按照年龄升序排列 select * from heroes where (age between 20 and 70) and gender=1 order by age; select * from heroes where (age between 20 and 70) and gender=1 order by age asc; -- order by 多个字段 -- 查询年龄在16-24之间的女性,按身高降序排列,如相同,按年龄升序排列 select * from heroes where (age between 16 and 20) and gender=2 order by height desc,age asc; -- 全部人员,按照年龄从小到大排列,身高从高到低 select * from heroes order by age, height desc;
五、聚合函数
-- 函数,带括号那种。 -- 总数 -- count -- 查询男英雄有多少人 select count(*) as "男英雄个数" from heroes where gender=1; -- 最大值 -- max -- 查询最大的年龄 select age from heroes; select max(age) from heroes; -- 查询女性最高身高 select max(height) as "最高身高" from heroes where gender=2; -- 求和 -- sum -- 所有人身高总和 select sum(height) from heroes; -- 平均值 -- avg -- 女性平均年龄,以下两种方式均可,此处目的在于说明select后面可以加运算式, -- 但此类统计中尽量避免第二种方式,例如在此数据表中,如果是平均身高的话,因为有一个null的存在... select avg(age) from heroes where gender=2; select sum(age)/count(*) from heroes where gender=2; --===================================== -- 通过下面的命令得到的是女性的个数 select count(*) from heroes where gender=2; -- 通过下面的命令得到的是女性的总身高 select sum(height) from heroes where gender=2; -- 以下两种方式得到的女性平均身高不相等 select avg(height) from heroes where gender=2; select sum(height)/count(*) from heroes where gender=2; --自然也是不相等的... select avg(height) from heroes; select sum(height)/count(*) from heroes; --===================================== -- 四舍五入 round(123.23 , 1) => 保留1位小数 --计算所有人的平均年龄,保留2位小数 select round(sum(age)/count(*), 2) from heroes; select round(avg(age), 2) from heroes; -- 男性的平均身高,保留2位小数 select round(avg(height), 2) from heroes where gender=1;
六、分组查询
-- 要和聚合搭配使用,才比较有意义 -- group by -- 按照性别分组,查询所有的性别 -- select 可以唯一标记每个分组的...东西 from heroes group by gender; select gender from heroes group by gender; -- 计算每种性别有多少人 select gender, count(*) from heroes group by gender; -- 此处的count(*) 是对每组的计算结果 -- 计算每组中的最大年龄、平均年龄 select gender, max(age) from heroes group by gender; select gender, avg(age) from heroes group by gender; -- group_concat(...) -- 查询同种性别中的姓名等信息(查看组里的信息用 group_concat(想看的信息)) -- 统计每种性别都包括哪个英雄(数据多了,就可以统计,地区,部门等等) select gender, group_concat(name) from heroes group by gender; -- 计算男性的人数(先写where,再写group by) select gender,count(*) from heroes where gender=1 group by gender; -- 计算男性人数,并查看男性都包括谁 select gender,count(*), group_concat(name) from heroes where gender=1 group by gender; -- 计算男性人数,并查看男性都包括谁,以及每个人的id select gender,count(*), group_concat(name,id) from heroes where gender=1 group by gender; select gender,count(*), group_concat(name,"_",id," ",age) from heroes where gender=1 group by gender; -- having -- where 是从数据表中过滤数据,而having是从分组结果中过滤数据 -- 查询平均年龄超过40的性别,以及其中包含的人名 having avg(age) > 30 select gender, group_concat(name), avg(age) from heroes group by gender having avg(age) > 30; -- 查询人数多于2的性别 select gender, group_concat(name), count(*) from heroes group by gender having count(*) > 2;
七、分页查询
-- 例如 网页中选择页数 -- limit start(起始), count(个数) -- 限制查询出来的数据个数 select * from heroes where gender=1 limit 2; -- 查询前5个数据 select * from heroes limit 0, 5; -- 查询id 6-10(包含)的数据(id=1是第0个,id=6是第5个) select * from heroes limit 5, 5; -- 每页显示2个,显示第6页的信息,按照年龄升序排序(limit 放在命令末尾) select * from heroes order by age asc limit 10, 2; -- 查询所有女性信息,按升高降序,只显示前两个 -- 报错,刚开始想的..select gender, group_concat(name), age from heroes having gender=2 limit 2; select * from heroes where gender=2 order by height desc limit 2;
八、连接查询
-- 内连接 取多个表的交集,否则不显示 -- inner join ... on -- select * from 表1 inner join 表2; 将两张表对应起来 -- 表1 一行一行的来对应表2 所有行 select * from heroes inner join groups; -- 查询有能够对应小队的的英雄以及小队信息 -- select * from 表1 inner join 表2 on 条件; select * from heroes inner join groups on heroes.grp_id=groups.id; -- 按照要求显示姓名 小队 select heroes.*, groups.name from heroes inner join groups on heroes.grp_id=groups.id; select heroes.name, groups.name from heroes inner join groups on heroes.grp_id=groups.id; -- 给数据表起别名 select h.name, g.name from heroes as h inner join groups as g on h.grp_id=g.id; select h.name as "英雄", g.name as "小队" from heroes as h inner join groups as g on h.grp_id=g.id; -- 查询 有能够对应小队的英雄以及小队的信息,显示英雄的所有信息,只显示小队名称 select h.*, g.name from heroes as h inner join groups as g on h.grp_id=g.id; -- 在以上的查询中,将小队名字显示在第一列 select g.name, h.* from heroes as h inner join groups as g on h.grp_id=g.id; -- 查询有能够对应小队的的英雄以及小队信息,按照小队进行排序,当小队相同时,按英雄的id 升序排序 select g.name, h.* from heroes as h inner join groups as g on h.grp_id=g.id order by g.name,h.id; -- 左连接:以左边的表为基准去从右面的表取东西 -- left join -- 查询每位英雄对应的小组信息 select h.*, g.name from heroes as h left join groups as g on h.grp_id=g.id order by g.name,h.id; select h.*, g.name from heroes as h left join groups as g on h.grp_id=g.id; select * from heroes as h left join groups as g on h.grp_id=g.id; -- 查询没有对应班级信息的学生 select * from heroes as h left join groups as g on h.grp_id=g.id having g.id is null; select * from heroes as h left join groups as g on h.grp_id=g.id where g.id is null; -- 右连接 -- right join...on 用的很少 -- 将数据表名字互换位置,用left join即可完成
九、子查询
-- select 中套着一个select -- 查询最高的男英雄的信息 select * from heroes where height = (select max(height) from heroes where gender=1);
十、自关联
-- 一个表通过更改别名,当做两个表使用 -- select * from 表1 as 表A inner join 表1 as 表B on 表A.xxx=表B.yyy having 条件;
# 和时间赛跑