倡粤 发表于 2025-6-11 10:58:00

数据库DQL查询

MySQL数据库查询关键字

接下来会通过mysql的关键字来演示在数据库中如何对数据查询
mysql中的内置方法可以使用 'help function'来查看使用方式


[*]常用的mysql 查询相关关键字
数据库查询(DQL)
-- 语法
select
字段列表
from
表名列表
where
条件列表
group by
分组字段列表
having
过滤列表
distinct
去重列表
order by
排序字段列表
limit
分页
regexp
正则匹配关键字

"""
DQL执行顺序
FROM -> WHERE -> GROUP BY -> SELECT -> ORDER BY -> LIMIT
"""

[*]多表查询的两种方式

[*]子查询
[*]连表查询


[*]基础查询

[*]查询多个字段
-- 查询多个字段
select field1, field2.... from tablename;
or
select * from tablename;

-- 设置别名
select field1 as a1, field2 as a2,....from tablename;
or
select field1 a1, field2 as a2,... from tablename;


-- 去除重复记录
select distinct fieldlist from tablename;


-- 转义
select * from tablename where name like '/_张三/'escape'/'

[*]条件查询
-- grammar
select fieldlist from tablename where condition_list;比较运算符功能>大于>=大于等于</tdtd小于/td/trtrtd=/tdtd小于等于/td/trtrtd=/tdtd等于/td/trtrtd 或 !=/tdtd不等于/td/trtrtdBETWEEN....AND.../tdtd在某个范围内(含最小,最大值)/td/trtrtdIN (...)/tdtd在in之后的列表中的值,多选一/td/trtrtdLIKE 占位符/tdtd模糊匹配(_匹配单个字符,%匹配任意字符)/td/trtrtdIS NULL/tdtd是NULL/td/tr/tbody/tabletabletheadtrth逻辑运算符/thth功能/th/tr/theadtbodytrtdAND 或 &&/tdtd并且(多个条件同时成立)/td/trtrtdOR 或 ||/tdtd或者(多个条件任意成立一个)/td/trtrtdNOT 或 !/tdtd非,不是/td/tr/tbody/tabletabletheadtrth函数/thth功能/th/tr/theadtbodytrtdcount/tdtd统计数量/td/trtrtdmax/tdtd最大值/td/trtrtdmin/tdtd最小值/td/trtrtdsum/tdtd求和/td/trtrtdavg/tdtd平均值/td/tr/tbody/tablep代码实际应用/pblockquoteolli数据准备/lili查询使用/li/ol/blockquote/*
准备一张员工数据表,并写入测试数据
*/
create table emp(
    id int primary key auto_increment,
    name varchar(36) 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);ulli查询关键字-where筛选/li/ul1. 查询id大于等于3 小于等于6的数据
/*
分析: 只需要使用and链接两个条件即可
*/
select * from emp where id>=3 and id<=6;
select * from emp where id>=3 && id<=6;

2. 查询薪资是20000或者18000或者17000的数据
/*
分析: 可以使用or对多个条件进行匹配
    可以使用in对一个数据集中的数据做匹配
*/
select * from emp where salary=20000 or salary=18000 or salary=17000;
select * from emp where salary in (20000,18000,17000);

3. 查询员工姓名中包含字母o的员工姓名与薪资
/*
分析: 需要使用like模糊查询
*/
select name,salary from emp where name like '%o%';

4. 查询员工姓名是由四个字符组成的员工姓名与其薪资
/*
分析: 使用模糊查询单匹配字符_
*/
select name,salary from emp where name like '____';
select name.salary from emp where char_length(name) = 4;

5. 查询岗位描述为空的员工名与岗位名针对null不能用等号,只能用is
/*
分析: 针对null 不能使用=号,只能使用is
*/
select * from emp where post_comment is null;ulli查询关键字group by分组/li/ulblockquotepgroup by 分组就是将前面处理的数据作为新的数据集处,可以配合聚合函数br分组之后最小单位为组,不再是组内单个的数据/p/blockquoteselect * from emp where post;
-- 注意由于mysql中的严格模式要求,需要将分组后字段和select字段只能填写分组依据,这里的select * 不可用,这是由only_full_group_by配置来决定
mysql> select post from emp group by post;
-- 以post字段将数据分为4组
+-----------------------------+
| post                        |
+-----------------------------+
| operation                   |
| sale                        |
| teacher                     |
| 浦东第一帅形象代言 |
+-----------------------------+
4 rows in set (0.02 sec)


-- 需求:将员工数据按照部门分组,并获得每个部门最高工资
-- 在分组之后由select处理,可以用函数处理其他字段信息
select post,max(salary) from emp group by post;

-- 对打印的结果字段做别名
select post, max(salary) as '最高薪' from emp group by post;


-- 一次获取部门薪资相关统计
select post as '部门',max(salary) as '最高薪资', min(salary) as '最低薪资', avg(salary) as '平均薪资', sum(salary) as '薪水支出总额' from emp group by post;

-- 统计每个部门的人数
select post as '部门', count(id) as '人数' from emp group by post;


-- 统计每个部门的部门名称以及部门下的员工姓名
select post,group_concat(name) from emp group by post;
select post, group_concat(name,'_优秀员工') from emp group by post;ulli查询关键字-having过滤/li/ulblockquotephaving本质的区别和where是一样的,作为数据的筛选br区别: where是首次筛选,having是二次筛选,即对数据结果集再次处理/p/blockquote-- 统计各部门年龄在30岁以上的员工平均工资 并且保留大于10000的数据
/*
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;
*/
select post,avg(salary) from emp where age > 30 group by post having avg(salary) > 10000;

[*]查询关键字-distinct去重
注意,数据必须完全一致才能去重,多条数据也需要遵循
select distinct id,age from emp;
-- 这里id和age字段中必须完全一致才能被去重
/*
例如,符合要求
id 1age 18
id 1age 18
不符合要求
id 1age 18
id 2age 18
*/

[*]查询关键字 - order by 排序
asc :升序, desc :降序
-- 单字段排序
-- 升序
select age from emp order by acs;
-- 降序
select age from emp order by desc;

-- 多字段排序
/*
分析: 先对age进行升序,再更具salary降序,
*/
select * from emp order by age,salary desc;


/*
统计各部门年龄在10岁以上的员工平均工资,
并且保留平均工资大于1000的部门,
然后对平均工资进行排序
*/
select post,avg(salary) from emp where age > 10 group by post having avg(salary) > 1000 order by avg(salary) desc;

/*
使用as 别名降低语句执消耗资源
select post,avg(salary) as avg_s from emp where age > 10 group by post having avg_s > 1000 order by avg_s desc;
*/

[*]查询关键字- limit分页
对数据做截取处理,例如1000万数据,进行处理后可以使用limit 100 看前100条数据,也可以写100,100 看第100条数据开始的后100条
-- 前5条数据
select * from emp limit 5;
-- 第二条数据开始的后5条数据
select * from emp limit 2,5;
查询工资最高的人的详细信息
select * from emp order by salary desc limit 1;
+----+------+--------+-----+------------+---------+--------------+------------+--------+-----------+
| id | name | gender | age | hire_date| post    | post_comment | salary   | office | depart_id |
+----+------+--------+-----+------------+---------+--------------+------------+--------+-----------+
|2 | tom| male   |78 | 2015-03-02 | teacher | NULL         | 1000000.31 |    401 |         1 |
+----+------+--------+-----+------------+---------+--------------+------------+--------+-----------+
1 row in set (0.02 sec)

[*]查询关键字-regexp 正则表达式
模糊查询的第二种方式
select * from emp where name regexp '^j.*(n|y)$';
/*
如果出现1139错误请将正则中的?+ 去除或替换
1139 - Got error 'repetition-operator operand invalid' from regexp

POSIX regexes don't support using the question mark ? as a non-greedy (lazy) modifier to the star and plus quantifiers like PCRE (Perl Compatible Regular Expressions). This means you can't use +? and *?
*/

[*]多表查询思路
create table dep(
    id int primary key auto_increment,
    name varchar(20)
);


create table emp1(
    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 emp1(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 emp1, dep;
/*
在同时对两张表查询数据值称为:’笛卡尔积‘无脑对应没有意义,多表联查应该将
无关系的两张表通过语句指定逻辑关系
*/
select * from emp1, dep where emp1.dep_id=dep.id;
mysql> select * from emp1, dep where emp1.dep_id=dep.id;

+----+--------+--------+-----+--------+-----+--------------+
| id | name   | sex    | age | dep_id | id| name         |
+----+--------+--------+-----+--------+-----+--------------+
|1 | jason| male   |18 |    200 | 200 | 技术          |
|2 | dragon | female |48 |    201 | 201 | 人力资源       |
|3 | kevin| male   |18 |    201 | 201 | 人力资源       |
|4 | nick   | male   |28 |    202 | 202 | 销售          |
|5 | owen   | male   |18 |    203 | 203 | 运营          |
+----+--------+--------+-----+--------+-----+--------------+
5 rows in set (0.02 sec)
-- 基于上述的操作就可以将多张表合并到一起然后一次性获取更多的数据


-- 基于emp表格对数据做出筛选


1. 查询岗位名以及岗位包含的所有员工名字
select post,group_concat(name) from emp group by post;

2. 查询岗位名以及各岗位内包含的员工个数
select post as '部门',group_concat(name) as '部门成员',count(name) as '部门人数' from emp group by post;

3. 查询公司内男员工和女员工的个数
select gender as '性别',count(id) as '人数' from emp group by gender;

4. 查询岗位名以及各岗位的平均薪资
select post,avg(salary) from emp group by post;

5. 查询岗位名以及各岗位的最高薪资
select post,max(salary) from emp group by post;

6. 查询岗位名以及各岗位的最低薪资
select post,min(salary) from emp group by post;

7. 查询男员工与男员工的平均薪资,女员工与女员工的平均薪资
select gender as '性别',avg(salary) as '平均薪资' from emp group by gender;

8. 统计各部门年龄在30岁以上的员工平均工资
select post as '部门',avg(salary) as '平均薪资' from emp where age > 30 group by post;
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: 数据库DQL查询