SQL语句查询关键字
SQL语句查询关键字前戏
SQL语句中关键字的执行顺序和编写顺序并不是一致的,可能会错乱
eg:
select id,name from userinfo;
我们先写的select再写的from,但是执行的时候是先执行的from,再执行select
对应关键字的编写顺序和执行顺序我们没必要过多的在意,熟练之后会非常自然的编写,我们只需要把注意力放在每个关键字的功能上即可。
select
指定需要查询的字段信息
select * 查所有字段
select name 查name字段
select char_length(name) 支持对字段做处理
from
指定需要查询的表信息
from mysql.user
from t1
前期数据准备
create table emp(
id int primary key auto_increment,
name varchar(20) not null,
gender enum('male','female') not null default 'male', #大部分是男的
age int(3) unsigned not null default 28,
hire_date date not null,
post varchar(50),
post_comment varchar(100),
salary double(15,2),
office int, #一个部门一个屋子
depart_id int
); #插入记录
#三个部门:教学,销售,运营
insert into emp(name,gender,age,hire_date,post,salary,office,depart_id) values
('jason','male',18,'20170301','浦东第一帅形象代言',7300.33,401,1), #以下是教学部
('tom','male',78,'20150302','teacher',1000000.31,401,1),
('kevin','male',81,'20130305','teacher',8300,401,1),
('tony','male',73,'20140701','teacher',3500,401,1),
('owen','male',28,'20121101','teacher',2100,401,1),
('jack','female',18,'20110211','teacher',9000,401,1),
('jenny','male',18,'19000301','teacher',30000,401,1),
('sank','male',48,'20101111','teacher',10000,401,1),
('哈哈','female',48,'20150311','sale',3000.13,402,2),#以下是销售部门
('呵呵','female',38,'20101101','sale',2000.35,402,2),
('西西','female',18,'20110312','sale',1000.37,402,2),
('乐乐','female',18,'20160513','sale',3000.29,402,2),
('拉拉','female',28,'20170127','sale',4000.33,402,2),
('僧龙','male',28,'20160311','operation',10000.13,403,3), #以下是运营部门
('程咬金','male',18,'19970312','operation',20000,403,3),
('程咬银','female',18,'20130311','operation',19000,403,3),
('程咬铜','male',18,'20150411','operation',18000,403,3),
('程咬铁','female',18,'20140512','operation',17000,403,3);
编写SQL语句的小技巧
- 针对select后面的字段名可以先用*占位往后写,最后再回来修改
- 在实际应用中select后面很少直接写*, 因为*表示所有,当表中字段和数据都特别多的情况下非常浪费数据库资源。
- SQL语句的编写类似于代码的编写,不是一蹴而就的,也需要反反复复的修修补补。
查询关键字之where筛选
案例
1.查询id大于等于3小于等于6的数据
select * from emp where id >= 3 and id <= 6; 支持逻辑运算符
select * from emp where id between 3 and 6;
2.查询薪资是20000或者18000或者17000的数据
select * from emp where salary=20000 or salary=18000 or salary=17000;
select * from emp where salary in (20000,18000,17000); 支持成员运算
3.查询id小于3大于6的数据
select * from emp where id<3 or id>6;
select * from emp where id not between 3 and 6;
4.查询员工姓名中包含字母o的员工姓名与薪资
模糊查询
条件不够精确的查询,称之为“模糊查询”。
模糊查询的关键字是 like
模糊查询的常用符号
%:匹配任意个数的任意字符
eg:
%o% 所有含有o的字段
例:o jason owen loo wwoww %o 以o结尾的字段
例:o asdasdo asdo _:匹配单个个数的任意字符
eg:
_o_ o的左右两边各一个字符
例:aox wob iok
o_ o的右边一个字符
例:oi ok ol
5.查询员工姓名是由四个字符组成的员工姓名与其薪资
方法1:
select * from emp where name like '____';
方法2:
select * from emp where char_length(name) = 4;
6.查询岗位描述为空的员工名与岗位名
注意:针对null不能用等号,只能用is
select * from emp where post_comment=NULL; # 不可以
发现上述查到的结果为空。
把行号换成is就可以成功查找了:
select * from emp where post_comment is NULL; # 可以
说明:在MySQL中也有很多内置方法,我们可以通过查看帮助手册学习
help 方法名
查询关键字之group by分组
分组:按照指定的条件将单个单个的数据组成一个个整体
eg:
将班级学生按照性别分组
将全国人民按照民族分组
将全世界的人按照肤色分组
分组的目的是为了更好的统计相关数据
eg:
每个班级的男女比例
每个民族的总占比
每个部门的平均薪资
聚合函数
专门用于分组之后的数据统计
max\min\sum\avg\count
最大值、最小值、求和、平均值、计数
案例
1. 将员工数据按照部门分组
select * from emp group by post;
注意:
上述查询语句在MySQL5.7及8.0默认都会直接报错
原因是分组之后 select后面默认只能直接填写分组的依据,不能再写其他字段
select post from emp group by post;
select age from emp group by age;
分组之后默认的最小单位就应该是组,而不应该再是组内的单个数据、单个字段
MySQL5.6默认不会报错,需要修改严格模式:
set global sql_mode='strict_trans_tables,only_full_group_by';
2. 获取每个部门的最高工资
要不要分组我们完全可以从题目的需求中分析出来,尤其是出现关键字——每个、平均
select post,max(salary) from emp group by post;
针对sql语句执行之后的结果,我们是可以修改字段名称的,关键字as,也可以省略
select post as '部门',max(salary) as '最高薪资' from emp group by post;
3. 一次获取部门薪资相关统计
select post,max(salary) '最高薪',min(salary) '最低薪',avg(salary) '平均薪资',sum(salary) '月支出' from emp group by post;
4. 统计每个部门的人数
select post,count(id) from emp group by post;
5.统计每个部门的部门名称以及部门下的员工姓名
select post,name from emp group by post; # ERROR 1055 (42000): 'db4.emp.name' isn't in GROUP BY
上述执行会报错,是因为分组以外的字段无法直接填写,需要借助于方法
group_concat():分组之后按照括号里的字段将相关信息拼接到一起
select post,group_concat(name) from emp group by post;
select post,group_concat(name,age) from emp group by post;
拼接字段中我们可以设置不同的格式:
1. 将名字和年龄之间用符号隔开
select post,group_concat(name,'|',age) from emp group by post;
2. 给名字添加后缀
select post,group_concat(name,'_NB') from emp group by post;
3. 给名字添加前缀和后缀
select post,group_concat('DSB_',name,'_NB') from emp group by post;
查询关键字之having过滤
having与where本质是一样的,都是用来对数据做筛选,只不过where用在分组之前(首次筛选),having用在分组之后(二次筛选)。
案例
1.统计各部门年龄在30岁以上的员工平均工资,并且保留大于10000的数据
说明:
稍微复杂一点的SQL 跟写代码几乎一样,也需要提前想好大致思路
每条SQL的结果可以直接看成就是一张表,基于该表如果还想继续操作则直接在产生该表的SQL语句上添加即可
步骤1:先筛选出所有年龄大于30岁的员工数据
select * from emp where age > 30;
步骤2:再对筛选出来的数据按照部门分组并统计平均薪资
select post,avg(salary) from emp where age > 30 group by post;
步骤3:针对分组统计之后的结果做二次筛选
select post,avg(salary) from emp where age > 30 group by post having avg(salary) > 10000;
查询关键字之distinct去重
去重有一个必须的条件也是很容易被忽略的条件——数据必须一模一样才可以去重。
select distinct id,age from emp;
关键字针对的是多个字段组合的结果,id和name的组合没有一模一样的,所以上述无法去重。
select distinct age from emp;
select distinct age,post from emp;
查询关键字之order by排序
1.单个字段排序
select * from emp order by age;
# 按照年龄升序排列
2.多个字段排序
select * from emp order by age,salary desc;
# 先按照年龄升序排列,再在此基础上按照薪资降序排列
练习
统计各部门年龄在10岁以上的员工平均工资,并且保留平均工资大于1000的部门,然后对平均工资进行排序。
1.先筛选出所有年龄大于10岁的员工
select * from emp where age > 10;
2.再对他们按照部门分组统计平均薪资
select post,avg(salary) from emp where age > 10 group by post;
3.针对分组的结果做二次筛选
select post,avg(salary) from emp where age > 10 group by post having avg(salary)>1000;
4.最后按照指定字段排序
select post,avg(salary) from emp where age > 10 group by post having avg(salary)>1000 order by avg(salary);
PS:当一条SQL语句中很多地方都需要使用聚合函数计算之后的结果,我们可以节省操作,给该结果取一个别名(主要是节省了底层运行效率,代码看不出来)
select post,avg(salary) as avg_salary from emp where age > 10 group by post having avg_salary>1000 order by avg_salary;
注意,如果在取别名时出现报错,可能是严格模式'only_full_group_by'引起,只需要将此严格模式去掉即可。
查询关键字之limit分页
当表中数据特别多的情况下,我们很少会一次性获取所有的数据,很多网站也是做了分页处理,一次性只能看一点点。
select * from emp limit 5; # 直接限制展示的条数
select * from emp limit 5,5; # 从第5条开始往后读取5条
练习
查询工资最高的人的详细信息。(注意:千万不要惯性思维,一看到工资最高就想着用分组聚合)
select * from emp order by salary desc limit 1;
查询关键字之regexp正则表达式
SQL语句的模糊匹配如果用不习惯,也可以自己写正则批量查询
select * from emp where name regexp '^j.*?(n|y)$';
# 注意,有些版本的msq会报错,把?去掉即可
多表查询的思路
表数据准备
create table dep(
id int primary key auto_increment,
name varchar(20)
); create table emp(
id int primary key auto_increment,
name varchar(20),
sex enum('male','female') not null default 'male',
age int,
dep_id int
); #插入数据
insert into dep values
(200,'技术'),
(201,'人力资源'),
(202,'销售'),
(203,'运营'),
(205,'财务'); insert into emp(name,sex,age,dep_id) values
('jason','male',18,200),
('dragon','female',48,201),
('kevin','male',18,201),
('nick','male',28,202),
('owen','male',18,203),
('jerry','female',18,204);
查询案例
select * from emp,dep;
上述指令会将两张表中所有的数据对应一遍
这个现象我们也称之为'笛卡尔积' ,无脑的对应没有意义,应该将有关系的数据对应到一起才合理。
基于笛卡尔积可以将部门编号与部门id相同的数据筛选出来。
涉及到两张及以上的表时,字段很容易冲突,我们需要在字段前面加上表名来指定
select * from emp,dep where emp.dep_id=dep.id;
基于上述的操作就可以将多张表合并到一起然后一次性获取更多的数据。
多表查询的两种方法
方式1:连表操作
inner join 内连接
select * from emp inner join dep on emp.dep_id=dep.id;
# 只连接两张表中公有的数据部分
left join 左连接
select * from emp left join dep on emp.dep_id=dep.id;
# 以左表为基准 展示左表所有的数据 如果没有对应项则用NULL填充
right join 右连接
select * from emp right join dep on emp.dep_id=dep.id;
# 以右表为基准 展示右表所有的数据 如果没有对应项则用NULL填充
union 全连接
select * from emp left join dep on emp.dep_id=dep.id
union
select * from emp right join dep on emp.dep_id=dep.id;
# 以左右表为基准 展示所有的数据 各自没有的全部NULL填充
学会了连表操作之后也就可以连接N多张表。
思路:将拼接之后的表起别名当成一张表再去与其他表拼接,再起别名当一张表,再去与其他表拼接,其次往复即可。
方式2: 子查询
将一条SQL语句用括号括起来当成另外一条SQL语句的查询条件
题目: 求姓名是jason的员工部门名称
子查询类似于我们日常生活中解决问题的方式>>>:分步操作
步骤1:先根据jason获取部门编号
select dep_id from emp where name='jason';
步骤2:再根据部门编号获取部门名称
select name from dep where id=200;
总结:
select name from dep where id=(select dep_id from emp where name='jason');
很多时候多表查询需要结合实际情况判断用哪种,更多时候甚至是相互配合使用。
小知识点补充说明
1.concat与concat_ws
concat用于分组之前的字段拼接操作
select concat(name,'$',sex) from emp;
concat_ws拼接多个字段并且中间的连接符一致
select concat_ws('|',name,sex,age,dep_id) from emp;
2.exists
sql1 exists sql2
sql2有结果的情况下才会执行sql1 否则不执行sql1 返回空数据
select * from dep where exists(select * from emp where emp.id>100);
select * from dep where exists(select * from emp where emp.id>1);
3.表相关SQL补充
# 修改表名
alter table 表名 rename 新表名;
# 添加字段
alter table 表名 add 字段名 字段类型(数字) 约束条件;
alter table 表名 add 字段名 字段类型(数字) 约束条件 after 已有字段;
alter table 表名 add 字段名 字段类型(数字) 约束条件 first;
# 修改字段
alter table 表名 change 旧字段名 新字段名 字段类型(数字) 约束条件;
alter table 表名 modify 字段名 新字段类型(数字) 约束条件;
# 删除字段
alter table 表名 drop 字段名;
SQL语句查询关键字的更多相关文章
- SQL语句查询关键字中含有特殊符号怎么处理, 例如 'SMI_'
SQL语句查询关键字中含有特殊符号怎么处理, 例如 'SMI_' 错误:select * from emp where ename like '%SML_%' 正确:select * from em ...
- 怎样用SQL语句查询一个数据库中的所有表?
怎样用SQL语句查询一个数据库中的所有表? --读取库中的所有表名 select name from sysobjects where xtype='u'--读取指定表的所有列名select nam ...
- sql语句查询
1. sql语句查询某位数字或者某几位数字开头的数据,字段类型为数字类: %’: 2. sql搜索以4开头和含有李字的数据: select * from wlzbpre_user where real ...
- phpcmsv9自定义sql语句查询模型实现
在phpcmsv9中,自定义sql语句查询可不太好实现,传入sql语句查询很容易被内部转入生成一系列莫名其妙的sql语句,比如最佳前缀等等,直接造成sql语句查询错误,在此也提供两种解决办法,1修改底 ...
- SQL语句查询某表的所有字段及数据类型
SQL语句查询某表的所有字段及数据类型 SELECT name AS column_name , TYPE_NAME(system_type_id) AS column_type , max_leng ...
- sql语句查询数据库表结构信息
开发中经常用到查询指定表及其字段的信息,以下是我整理的SQL语句查询方法,供自己平时使用也提供给大家参考! 1.适用MS SQL SERVER: SELECT 表名 = then d.name els ...
- 如何用SQL语句查询Excel数据?
如何用SQL语句查询Excel数据?Q:如何用SQL语句查询Excel数据? A:下列语句可在SQL SERVER中查询Excel工作表中的数据. 2007和2010版本: SELECT*FROMOp ...
- 怎么用sql语句查询一个数据库有多少张表
今天在技术群中闲谈时忽然聊到一个问题,那就是当一个数据库中有多张表时怎么快速的获取到表的个数,从而给问询者一个准确的回答. 大家或许会说,这个问题和我们的数据库操作没有太大关系或者不是很挂钩,所以没意 ...
- 使用sql语句查询日期在一定时间内的数据
使用sql语句查询日期在一周内的数据 select * from ShopOrder where datediff(week,ordTime,getdate()-1)=0 //查询当天日期在一周年 ...
- SQL语句查询数据库的触发器、存储过程、视图以及表的SQL语句
Sql Server数据库用SQL语句查询方法如下: select name from sysobjects where xtype='TR' --所有触发器 select name from sys ...
随机推荐
- PR中导入的照片在画面上只显示一部分的解决办法
这是因为图片的分辨率太大导致的. 1.图片的分辨率大于PR工程的设置的时候,就会只显示局部. 2.可以用PS把图片先缩小为工程大小即可. 3.也可以把图片拖到时间线上,右键点击,缩放为帧大小即可. 这 ...
- Oracle基础知识汇总一
Oracle基础知识 以下内容为本人的学习笔记,如需要转载,请声明原文链接 https://www.cnblogs.com/lyh1024/p/16720759.html oracle工具: SQ ...
- C++ 队列!还是要从 STL 中的说起……
1. 前言 队列和栈一样,都是受限的数据结构. 队列遵循先进先出的存储原则,类似于一根水管,水从一端进入,再从另一端出去.进入的一端称为队尾,出去的一端称为队头. 队列有 2 个常规操作: 入队:进入 ...
- HTTPS实现原理分析
概述 在上一节中介绍了两种加密方法 对称加密 非对称加密 其中对称加密性能高,但是有泄露密钥的风险,而非对称加密相反,加密性能较差,但是密钥不易泄露,那么能不能把他们进行一下结合呢? HTTPS采用混 ...
- 【Firefox浏览器】关闭触摸板双指滑动进行前进后退的功能
痛点 本以为只是Chrome浏览器存在这一奇葩功能,没成想Firefox也沦陷了!有好一阵子在使用Firefox的时候,并未发现其存在这个功能.直到有一天,打开自己的博客,翻阅上篇< [Chro ...
- java程序员在交接别人的工作时如何保证顺利交接?
序言 各位好啊,我是会编程的蜗牛,作为java开发者,尤其是在职场混迹了多年的老手,肯定会遇到同事离职的情况,或者自己跳槽的情况,这些都免不了需要做好交接工作,不管是别人交接给我们,还是我们交接给别人 ...
- Jquery中Trigger()方法
1. $(selector).trigger(event,[param1,param2,...]) 方法触发被选元素标签的指定事件类型 为元素边赋值为true,并触发元素标签的change方法 $(' ...
- 八、Django的组件
8.1.中间件 中间件顾名思义,是介于request与response处理之间的一道处理过程,相对比较轻量级,并且在全局上改变django的输入与输出.因为改变的是全局,所以需要谨慎实用,用不好会影响 ...
- 六、模型层(ORM)
六.模型层(ORM) Django中内嵌了ORM框架,不需要直接编写SQL语句进行数据库操作,而是通过定义模型类,操作模型类来完成对数据库中表的增删改查和创建等操作. O是object,也就类对象的意 ...
- 一次 Java log4j2 漏洞导致的生产问题
一.问题 近期生产在提交了微信小程序审核后(后面会讲到),总会出现一些生产告警,而且持续时间较长.我们查看一些工具和系统相关的,发现把我们的 gateway 差不多打死了. 有一些现象. 网关有很多接 ...