七.基本查询

1.基本查询

(1).概念

[1].数据库管理系统一个重要功能就是数据查询,数据查询不应只是简单返回数据库中存储的数据,还应该根据需要对数据进行筛选以及确定数据以什么样的格式显示。

[2].MySQL提供了功能强大,灵活的语句来实现这些操作

[3].MySQL数据库使用select语句来查询数据。

(2).语法格式

select
  [all|distinct]
  <目标列的表达式1> [别名],
  <目标列的表达式1> [别名] ...
from <表名或视图名> [别名],  <表名或视图名> [别名] ...
[where<条件表达式>]
[group by <列名>
[having <条件表达式>]]
[order by <列名> [asc|desc]]
[limit <数字或者列表>]

简化版语法:

select *| 列名 fromwhere 条件

(3).示例

[1].数据准备
[a].创建数据库和表

-- 创建数据库和表
create database if not exist mydb2;
use mydb2;
-- 创建商品表:
create table product(
  pid int primary key auto_increment, -- 商品编号
  pname varchar(20) not null, -- 商品名字
  price double, -- 商品价格
  category_id varchar(20) -- 商品所属分类  
);

[b].添加数据

insert into product values(null, '海尔洗衣机', 5000, 'c001');
insert into product values(null, '美的冰箱', 3000, 'c001');
insert into product values(null, '格力空调', 5000, 'c001');
insert into product values(null, '九阳电饭煲', 5000, 'c001');

insert into product values(null, '啄木鸟衬衣', 300, 'c002');
insert into product values(null, '恒源祥西裤', 800, 'c002');
insert into product values(null, '花花公子夹克', 440, 'c002');
insert into product values(null, '劲霸休闲裤', 266, 'c002');
insert into product values(null, '海澜之家卫衣', 180, 'c002');
insert into product values(null, '杰克琼斯运动裤', 430, 'c002');

insert into product values(null, '兰蔻面霜', 300, 'c003');
insert into product values(null, '雅诗兰黛精华水', 200, 'c003');
insert into product values(null, '香奈儿香水', 350, 'c003');
insert into product values(null, 'SK-II神仙水', 350, 'c003');
insert into product values(null, '资生堂粉底液', 180, 'c003');

insert into product values(null, '老北京方便面', 56, 'c004');
insert into product values(null, '良品铺子海带丝', 17, 'c004');
insert into product values(null, '三只松鼠坚果', 88, null);

[2].简单查询

-- 1.查询所有的商品
select * from product;
-- 2.查询商品名和商品价格
select pname, price from product;
-- 3.别名查询 使用的关键字是as (as可以省略的)
-- 3.1 表别名
select * from product as p;
-- 3.2 列别名
select pname as pn from product;
-- 4.去掉重复值
select distinct price from product;
-- 5.查询结果是表达式(运算查询):将所有商品的价格+10元
select pname, price+10 from product;

2.运算符

(1).简介

数据库中的表结构确立后,表中的数据代表的意义就已经确定。通过MySQL运算符进行运算,就可以获取到表结构以外另一种数据。

例如,学生表中存在一个birth字段,这个字段表示这个学生的出生年份。而运用MySQL运算符用当前年份减去学生出生的年份,那么得到的就是这个学生的实际年龄数据

(2).MySQL支持4种运算符

[1].算术运算符

[2].比较运算符

[3].逻辑运算符

[4].位运算符

(3).算术运算符

[1].分类

算术运算符说明
+加法运算
-减法运算
*乘法运算
/ 或 DIV除法运算,返回商
% 或 MOD求余运算,返回余数

[2].示例

select 6 + 2;
select 6 - 2;
select 6 * 2;
select 6 / 2;
select 6 % 2;

-- 将每件商品的价格加10
select name, price + 10 as new_price from product;
-- 将所有商品的价格上调10%
select pname, price * 1.1 as new_price from product;

(4).比较运算符

[1].分类

比较运算符说明
=等于
< 和 <=小于和小于等于
> 和 >=大于和大于等于
<=>安全的等于,两个操作码均为NULL时,其所得值为1;而当一个操作码为NULL时,其所得值为0
<>或!=不等于
IS NULL 或 ISNULL判断一个值是否为NULL
IS NOT NULL判断一个值是否不为NULL
LEAST当有两个或多个参数时,返回最小值
GAEATEST当有两个或多个参数时,返回最大值
BETWEEN AND判断一个值是否落在两个值之间
IN判断一个值是IN列表中的任意一个值
NOT IN判断一个值不是IN列表中的任意一个值
LIKE通配符匹配
REGEXP正则表达式匹配

[2].示例

-- 查询商品名称为"海尔洗衣机"的商品所有信息
select * from product where pname = '海尔洗衣机';

-- 查询价格为800商品
select * from product where price = 800;

-- 查询价格不是800的所有商品
select * from product where price != 800;
select * from product where price <> 800;
select * from product where not(price = 800);

-- 查询商品价格大于60元的所有商品信息
select * from product where price > 60

-- 查询商品价格在200到1000之间所有商品
select * from product where price >= 200 and price <= 1000;
select * from product where price between 200 and 1000;

-- 查询商品价格是200或800的所有商品
select * from product where price = 200 or price = 800;
select * from product where price in (200, 800);

-- 查询含有'鞋'字的所有商品
select * from product where pname like '%鞋%';

-- 查询以'海'开头的所有商品
select * from product where pname like '海%';

-- 查询第二字为'蔻'的所有商品
select * from product where pname like '_蔻%';

-- 查询category_id为null的商品
select * from product where category_id is null;

-- 查询category_id不为null的商品
select * from product where category_id is not null;

-- 使用least求最小值
select least(10, 20, 30); -- 10
select least(10, null, 30); -- null

-- 使用greatest求最大值
select greatest(10, 20, 30); -- 30
select greatest(10, null, 30); -- null

(5).逻辑运算符

[1].分类

逻辑运算符说明
NOT 或者 |逻辑非
AND 或者 &&逻辑与
OR 或者 ||逻辑或
XOR逻辑异或

(6).位运算

[1].分类

位运算符说明
|按位或
&按位与
^按位异或
<<按位左移
>>按位右移
~按位取反,反转所有比特

注意:位运算符是在二进制数上进行计算的运算符。

[2].示例

select 3&5; -- 位与
select 3|5; -- 位或
select 3^5; -- 位异或
select 3>>1; -- 位左移
select 3<<1; -- 位右移
select ~3; -- 位取反

3.排序查询

(1).概念

如果我们需要对读取的数据进行排序,我们就可以使用MySQL的order by子句来设定你想那个字段那种排序方式来进行排序,再返回搜索结果。

(2).语法

select 
   字段名1, 字段名2, ...
from 表名
order by 字段名1 [asc|desc], 字段名2 [asc|desc] ... 

(3).特点

[1].asc代表升序, desc代表降序,如果不写默认升序。

[2].order by用于子句中可以支持单个字段,多个字段,表达式,函数,别名

[3].order by子句,放在查询语句的最后面,LIMIT子句除外

(4).示例

-- 1.使用价格顺序(降序)
select * from product order by price desc;
-- 2.在价格排序(降序)的基础上,以分类排序(升序)
select * from product order by price desc, category asc;
-- 3.显示商品的价格(去重复),并排序(降序)
 select distinct price from product order by price desc;

4.聚合查询

(1).概念

之前我们做的查询都是横向查询,它们都是根据条件一行一行的进行判断,而使用聚合函数查询是纵向查询,它是一列的值进行计算,然后返回一个单一的值;另外聚合函数会忽略空值。

(2).聚合函数

聚合函数作用
count()统计指定列不为NULL的记录行数
sum()计算指定列的数值和,如果指定列类型不是数值类型,那么计算结果为0
max()计算指定列的最大值,如果指定列是字符串类型,那么使用字符串排序运算;
min()计算指定列的最小值,如果指定的列是字符串类型,那么使用字符串排序运算;
avg()计算指定列的平均值,如果指定列类型不是数值类型,那么计算结果为0

(3).示例

-- 1.查询商品的总条数
select count(pid) from product;
select count(*) from product;

-- 2.查询价格大于200商品的总条数
select count(pid) from product where price > 200;

-- 3.查询分类为'c001'的所有商品价格的总和
select sum(price) from product where category_id = 'c001';

-- 4.查询商品的最大价格
select max(price) from product;

-- 5.查询商品的最小价格
select min(price) from product;

-- 6.查询分类为'c002'所有商品的平均价格
select avg(price) from product where category_id = 'c002';

(4).Null值处理

[1].简介

[a]. count函数对null值的处理:

​ 如果count函数的参数为星号(*), 则统计所有记录的个数。而如果参数为某个字段,不统计含null值的记录个数。

[b].sum和avg函数对null值的处理

​ 这两个函数忽略null值的存在,就好像该条记录不存在一样。

​ [c].max和min函数对null值的处理

​ max和min两个函数同样忽略null值的存在

[2].示例

-- 创建表
create table test_null(
  c1 varchar(20),
  c2 int  
);

-- 插入数据
insert into test_null values('aaa', 3);
insert into test_null values('bbb', 3);
insert into test_null values('ccc', null);
insert into test_null values('ddd', 6);

-- 测试
select count(*), count(1), count(c2) from test_null;
select sum(c2), max(c2), min(c2), avg(c2) from test_null;

5.分组查询

(1).简介

分组查询是指使用group by子句对查询信息进行分组

(2).格式

select 字段1, 字段2 ... from 表名 group by 分组字段 having 分组条件;

(3).示例

-- 1.统计各个分类商品的个数
select category_id, count(*) from product group by category_id;

(4).分组之后的条件筛选-having

[1].分组之后对统计结果进行筛选的话必须使用having, 不能使用where

[2].where子句用来筛选FROM子句中指定的操作所产生的行

[3].group by子句用来分组WHERE子句的输出

[4].having子句用来从分组结果中筛选行。

-- 统计各个分类商品的个数,且只显示个数大于4的信息
select category_id, count(*) from product group by category_id having count(*) > 4;

6.分页查询

(1).简介

分页查询在项目中常见,由于数据量大,显示屏长有限,因此对数据采取分页显示方式。例如,数据共有30条,每页显示5条,第一页显示15条,第二页显示610条

(2).格式

-- 方式1 - 显示前n条
select 字段1, 字段2 ... from 表名 limit n
-- 方式2 - 分页显示
select 字段1, 字段2 ... from 表名 limit m, n
参数:
  m: 整数, 表示从第几条索引开始,计算方式(当前页 - 1) * 每页显示条数
  n: 整数, 表示查询多少条数据   

(3).示例

-- 查询product表的前5条记录
select * from product limit 5

-- 从第4条开始显示,显示5条
select * from product limit 3,5

7.insert into select语句

(1).简介

将一张表的数据导入到另一张表中,可以使用insert into select语句

(2).格式

insert into table2(field1, field2, ...) select value1, value2, ... from table1;
或者
insert into table2 select * from table1;

8.举例

(1).案例1

[1].数据准备

-- 创建数据库
create database mydb2;
use mydb2;

-- 创建表
create table student(
    id int,
    name varchar(20),
    gender varchar(20),
    chinese int,
    english int,
    math int  
);

-- 插入数据
insert into student(id, name, gender, chinese, english, math) values(1, '张明', '男', 89, 78, 90); 
insert into student(id, name, gender, chinese, english, math) values(2, '李进', '男', 67, 53, 95); 
insert into student(id, name, gender, chinese, english, math) values(3, '王五', '女', 87, 78, 77); 
insert into student(id, name, gender, chinese, english, math) values(4, '李一', '女', 88, 98, 92); 
insert into student(id, name, gender, chinese, english, math) values(5, '李财', '男', 82, 84, 67); 
insert into student(id, name, gender, chinese, english, math) values(6, '张宝', '男', 55, 85, 45); 
insert into student(id, name, gender, chinese, english, math) values(7, '黄蓉', '女', 75. 65, 30); 
insert into student(id, name, gender, chinese, english, math) values(7, '黄蓉', '女', 75, 65, 30); 

[2].查询

-- 查询表中所有学生的信息
select * from student;

-- 查询表中所有学生和对应的英语成绩
select name, english from student;

-- 过滤表中重复数据
select distinct * from student;

-- 统计每个学生的总分
select name, (chinese + english + math) as total_score from student;

-- 在所有学生总分数上加10分特长分
select name, (chinese + english + math + 10) as total_score from student;

-- 使用别名表示学生分数
select name, chinese '语文成绩', english '英语成绩', math '数学成绩' from student

-- 查询英语成绩大于90分的同学
select * from student where english > 90;

-- 查询总分大于200分的所有同学
select * from student where (chinese + english + math) > 200;

-- 查询英语分数在80~90之间的同学
select * from student where english between 80 and 90;
或者
select * from student where english >=80 and english <= 90;

-- 查询英语分数不在80~90之间同学
select * from student where not (english between 80 and 90);
或者
select * from student where english not between 80 and 90;
或者
select * from student where not (english >=80 and english <= 90);
或者
select * from student where english < 80 or english >90;

-- 查询数学分数为89, 90, 91的同学
select * from student where math in (89, 90, 91);

-- 查询数学不为分数为89, 90, 91的同学
select * from student where math not in (89, 90, 91);

-- 查询所有姓李的学生英语成绩
select name, english from student where name like '李%';

-- 查询数学分为80并且语文分为80的同学
select * from student where math = 80 and chinese = 80;

-- 查询英语80或者总分200同学
select * from student where math = 80 or (chinese + math + english) = 200;

-- 对数学成绩降序排序输出
select * from student order by math desc;

-- 对总分排序后输出,然后再从高到低的顺序输出
select * from student order by (chinese + math + english) desc;

-- 对姓李的同学总分成绩排序输出
select * from student where name like '李%' order by (chinese + math + english) desc;

-- 查询男生和女生分别有多少人,并将人数降序排序排序输出,并查询出人数大于4的性别人数信息
select gender, count(*) as total_cnt from student group by gender having total_cnt >4 order by total_cnt desc;

(2).案例2

[1].准备数据

create table emp(
     empno INT, -- 员工编号
     ename varchar(50), -- 员工姓名
     job varchar(50), -- 工作名字
     mgr INT, -- 上级领导编号
     hiredate DATE, -- 入职日期
     sal INT, -- 薪资
     comm INT, -- 奖金
     deptno INT -- 部门编号
);
INSERT INTO emp VALUES (7369, 'SMITH', 'CLERK', 7902, '1980-12-17', 800, NULL, 20);
INSERT INTO emp VALUES (7499, 'ALLEN', 'SALESMAN', 7698, '1981-02-20', 1600, 300, 30);
INSERT INTO emp VALUES (7521, 'WARD', 'SALESMAN', 7698, '1981-02-22', 1250, 500, 30);
INSERT INTO emp VALUES (7566, 'JONES', 'MANAGER', 7839, '1981-04-02', 2975, NULL, 20);
INSERT INTO emp VALUES (7654, 'MARTIN', 'SALESMAN', 7698, '1981-09-28', 1250, 1400, 30);
INSERT INTO emp VALUES (7698, 'BLAKE', 'MANAGER', 7839, '1981-05-01', 2450, NULL, 10);
INSERT INTO emp VALUES (7782, 'CLARK', 'MANAGER', 7839, '1981-06-09', 3000, NULL, 20);
INSERT INTO emp VALUES (7788, 'SCOTT', 'ANALYST', 7566, '1987-04-19', 5000, NULL, 20);
INSERT INTO emp VALUES (7839, 'KING', 'PRESIDENT', NULL, '1981-11-17', 2000, NULL, 10);
INSERT INTO emp VALUES (7844, 'TURNER', 'SALESMAN', 7698, '1981-19-08', 1500, 0, 30);
INSERT INTO emp VALUES (7876, 'ADAMS', 'CLERK', 7788, '1987-05-23', 1100, NULL, 20);
INSERT INTO emp VALUES (7900, 'JAMES', 'CLERK', 7698, '1981-12-03', 950, NULL, 30);
INSERT INTO emp VALUES (7902, 'FORD', 'ANALYST', 7566, '1981-12-03', 3000, NULL, 20);
INSERT INTO emp VALUES (7934, 'MILLER', 'CLERK', 7782, '1982-01-23', 1300, NULL, 10);

[2].按员工编号升序排列不在10号部门工作的员工信息

select * from emp where deptno != 10 order by empno asc; 

[3].查询姓名第二个字母不是’A’且薪水大于1000元的员工信息,按年薪降序排列

 -- 年薪:12*月薪 + 奖金 
 select * from emp where ename not like '_A%' and sal > 1000 order by(12*sal + ifnull(comm, 0)) desc;

[4].求每个部门的平均薪水

 select deptno, avg(sal) as avg_sal from emp group by deptno;  

[5].求各个部门的最高薪水

  select deptno, max(sal) as max_sal from emp group by deptno;   

[6].求每个部门每个岗位的最高薪水

  select deptno, job, max(sal) as max_sal from emp group by deptno, job;        

[7].求平均薪水大于2000的部门编号

select deptno, avg(sal) as avg_sal from emp group by deptno having avg_sal > 2000;      

[8].将部门平均薪水大于1500的部门编号列出来,按部门平均薪水降序排列

select deptno, avg(sal) as avg_sal from emp group by deptno having avg_sal > 2000 order by avg_sal desc;  

[9].选择公司中有奖金的员工姓名,工资

select * from emp where comm is not null;

[10].查询员工最高工资和最低工资的差距

select max(sal) - min(sal) as '薪资差距' from emp;   
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是实现该需求的代码: ``` #include <stdio.h> #include <string.h> #define MAX_SIZE 5 struct Employee { char name[20]; float basic_salary; float floating_salary; float deduction; float net_salary; }; void calculate_salary(struct Employee* emp) { emp->net_salary = emp->basic_salary + emp->floating_salary - emp->deduction; } int main() { struct Employee employees[MAX_SIZE]; int i, j; char query_name[20]; // 输入员工信息 printf("请输入%d个员工的信息:\n", MAX_SIZE); for (i = 0; i < MAX_SIZE; i++) { printf("请输入第%d个员工的姓名:", i + 1); scanf("%s", employees[i].name); printf("请输入该员工的基本工资:"); scanf("%f", &employees[i].basic_salary); printf("请输入该员工的浮动工资:"); scanf("%f", &employees[i].floating_salary); printf("请输入该员工的扣除部分:"); scanf("%f", &employees[i].deduction); calculate_salary(&employees[i]); // 计算实发工资 } // 查询员工实发工资 printf("\n请输入要查询的员工姓名(输入 # 列出所有员工):"); scanf("%s", query_name); if (strcmp(query_name, "#") == 0) { // 列出所有员工的实发工资 printf("\n姓名\t实发工资\n"); for (j = 0; j < MAX_SIZE; j++) { printf("%s\t%.2f\n", employees[j].name, employees[j].net_salary); } } else { // 查询某个员工的实发工资 for (j = 0; j < MAX_SIZE; j++) { if (strcmp(query_name, employees[j].name) == 0) { printf("\n%s的实发工资是:%.2f\n", employees[j].name, employees[j].net_salary); break; } } if (j == MAX_SIZE) { printf("\n未找到名为%s的员工\n", query_name); } } return 0; } ``` 运行结果: ``` 请输入5个员工的信息: 请输入第1个员工的姓名:张三 请输入该员工的基本工资:2400 请输入该员工的浮动工资:800 请输入该员工的扣除部分:160 请输入第2个员工的姓名:李四 请输入该员工的基本工资:3600 请输入该员工的浮动工资:620 请输入该员工的扣除部分:50 请输入第3个员工的姓名:王五 请输入该员工的基本工资:5600 请输入该员工的浮动工资:0 请输入该员工的扣除部分:80 请输入第4个员工的姓名:赵六 请输入该员工的基本工资:2400 请输入该员工的浮动工资:300 请输入该员工的扣除部分:20 请输入第5个员工的姓名:钱 请输入该员工的基本工资:4300 请输入该员工的浮动工资:1300 请输入该员工的扣除部分:300 请输入要查询的员工姓名(输入 # 列出所有员工):张三 张三的实发工资是:3040.00 ``` 如果输入`#`,则会列出所有员工的实发工资: ``` 请输入要查询的员工姓名(输入 # 列出所有员工):# 姓名 实发工资 张三 3040.00 李四 4170.00 王五 5520.00 赵六 2680.00 钱 5300.00 ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值