【06】MySQL-查询数据

【06】MySQL-查询数据

注意:

1 当一个查询语句同时出现 wheregroup by , having , order by的时候,执行顺序和编写顺序是:

  1. 执行where xx对全表数据做筛选,返回第1个结果集;
  2. 针对第1个结果集使用group by分组,返回第2个结果集;
  3. 针对第2个结果集中的每一组数据执行select xx,有几组就执行几次,返回第3个结果集;
  4. 针对第3个结果集使用having xx进行筛选,返回第4个结果集;
  5. 针对第4个结果集排序。
  6. 即:where --> group by -->select -->having -->order by

🔵🔵🔵

2 HAVINGWHERE都是用来过滤数据,区别在哪?

HAVING 在数据分组之后进行过滤选择分组

​ 而 WHERE分组之前用来选择记录

​ WEHER`排除的记录不在分组内


基本格式:

SELECT 
	{* | <字段列表>}
	[
        FROM <1>,<2>....
        [
            WHERE <表达式>
            [GROUP BY <group by dedinition>]
            [HAVING <expression> [{<operator><expression>}...]]
            [ORDER BY <order by definition>]
            [LIMIT [<offset>,] <row count>]
        ]
    ]
    
SELECT [字段1,字段2,...字段n]
FROM [表或视图]
WHERE [查询条件]

  1. where条件查询
-- 查询不在20-30岁的员工
SELECT * 
FROM emp 
WEHER age NOT BETWEEN 20 AND 30-- like
-- 查询所有以‘b'开头的水果
SELECT *
FROM fruits
where f_name LIKE 'B%';

-- 查询名字包含'g'的水果
select * 
from fruits
where f_name like '%g%'

-- 查询以字母y结尾,并且前面只有4个字符的记录
select * 
from fruits
where f_name like '____y'

-- 查询结果不重复:distinct关键字
-- 格式:SELECT DISTINCT 字段名 FROM 表名
-- 查询所有有员工的部门编号
select distinct deptId from emp;

-- 对查询结果排序,order by
-- 指定排序方向 desc   降序排序
SELECT price 
FROM products 
ORDER BY DESC;

  1. group by分组
-- group by
-- 查询每个水果商提供的水果种类
select s_id, count(*) as Total
from fruits
group by s_id

-- 联合Having查询, ’并显示水果种类>1的分组信息
select s_id,GROUP_COUCAT(f_name) AS Names
from fruits
GROUP BY s_id 
HAVING COUNT(f_name) > 1

-- 在group by 子句中使用with rollup
-- WITH ROLLUP :在所有查询出的分组记录之后增加一条记录,
-- 该记录查询出所有的记录的综合,即统计记录数量

-- 根据s_id , 对fruit表中的数据进行分组,并显示记录数目
select s_id, count(*) as Total
from fruits
group by s_id WITH ROLLUP

-- 还可以多字段进行分组
  1. 分组后的Having操作
-- 查询订单价格大于100的订单号和总订单价格
SELECT o_num, SUM(querytity * item_price) AS orderTotal
FROM orderitems
GROUP BY o_num
HAVING SUM(querytity * item_price) >= 100;

-- 联合Order By
-- 对总订单价格进行排序
SELECT o_num, SUM(querytity * item_price) AS orderTotal
FROM orderitems
GROUP BY o_num
HAVING SUM(querytity * item_price) >= 100
ORDER BY orderTotal;

【07】MySQL-增删改

  1. 插入数据
-- 创建表
CREATE TABLE person
(
	id 	    INT UNSIGNED NOT NULL AUTO_INCREMENT,
    name    CHAR(40) NOT NULL DEFAULT '',
    age     INT NOT NULL DEFAULT 0,
    info    CHAR(50) NULL,
    PRIMARY KEY(id)
);

-- 插入
-- 1.单条插入(未指定列名
insert into person
values (1,'lishi',12,Lawyer);

-- 2.多条插入
insert into person
values (1,'lishi',12,Lawyer),
(null,'libai',32,Cleaner),
(null,'shushi',43,Student);
-- 注:这种一条insert语句插入多条数据
-- 比多条insert语句插入单条数据的效率高

-- 3.指定列名插入
insert into person(name,age,info)
values ('lishi',18,'Teacher');

-- 4.将查询结果插入到表内
CREATE TABLE person_new
(
	id 	    INT UNSIGNED NOT NULL AUTO_INCREMENT,
    name    CHAR(40) NOT NULL DEFAULT '',
    age     INT NOT NULL DEFAULT 0,
    info    CHAR(50) NULL,
    PRIMARY KEY(id)
);

-- 将旧表内数据插入到新表内
INSERT INTO person_new (id,name,age,info)
SELECT id,name,age,info
FROM person;
  1. 更新数据
-- 格式:update tab_name set coL_name1 = value1,col_name2 = value2 ...
-- where (condition)
-- 如果不使用where会更新整列
update person set age = 18 ,name = 'yangxu'
where id = 1;
  1. 删除数据
-- 格式:delete from tab_name [where <condition>]
delete from person
where id = 2;

练习:
-- p175:
USE market;
CREATE TABLE fruits
(
		f_id CHAR(10) NOT NULL,
		s_id INT NOT NULL,
		f_name CHAR(255) NOT NULL,
		f_price DECIMAL(8,2) NOT NULL,
		PRIMARY KEY(f_id)
);


-- 插入数据
INSERT INTO fruits VALUES
('a1',101,'apple',5.2),
('a2',102,'apple',5.2),
('a3',103,'apple',9.2),
('b1',101,'apple2',5.5),
('b2',106,'apple4',3.2),
('c1',102,'apple3',1.2),
('c2',103,'apple',7.2);

-- 查询
SELECT * FROM fruits;

-- 根据s_id对其分组
SELECT  s_id,count(*) AS Total FROM fruits GROUP BY s_id;

-- 根据s_id,fruits表中的数据进行分组,将每个水果供应商的水果名称打印出来
SELECT s_id,GROUP_CONCAT(f_name) AS Names 
FROM fruits 
GROUP BY s_id;

-- LIMIT
SELECT * FROM fruits LIMIT 0,2;

-- 集合函数查询 ,查询所有水果数目
/*
	注:count(*)和count(字段名)的区别?
count(*):计算表中总的行数,无论某列是否为null
count(字段名):计算时忽略null
*/
SELECT count(*) as TotalNum FROM fruits;

-- AVG():返回某列平均值
-- SUM():返回某列总和 ,忽略 NULL
-- Max(),Min() :返回某列最大最小值    

SELECT SUM(f_price) AS TotalCount FROM fruits WHERE s_id = 101;
 
SELECT MAX(f_price) AS max_price FROM fruits ;

SELECT MIN(f_price) AS min_price FROM fruits;

-- MAX(),MIN()    还可以用于查找字符类型
SELECT MAX(f_name) FROM fruits;


-- 查找fruits表中不同供应商提供的水果价格最高的水果
-- 分析:1.先按供应商分组,2.使用max()求最大
SELECT f_name,s_id,MAX(f_price) as max_price
FROM fruits
GROUP BY s_id;

/*
	* 当一个查询语句同时出现where,group by,having,order by的时候,执行顺序和编写顺序是:

			1. 执行where xx对全表数据做筛选,返回第1个结果集;
			2. 针对第1个结果集使用group by分组,返回第2个结果集;
			3. 针对第2个结果集中的每一组数据执行select xx,有几组就执行几次,返回第3个结果集;
			4. 针对第3个结果集使用having xx进行筛选,返回第4个结果集;
			5. 针对第4个结果集排序。
*/

-- 内连接  1.使用where
SELECT supperliers.s_id,s_name,f_name,f_price
FROM fruits
WHERE supperliers.s_id = fruits.s_id;

-- 内连接  2.使用‘ 表1 INNER JOIN 表2 ON 表1.id = 表2.id
SELECT supperlisers.s_id ,s_name,f_name,f_price
FROM fruits
INNER JOIN supperliers
ON fruits.s_id = supperliers.s_id;

-- 自连接   查询供应f_id = 'a1'的水果供应商提供的其他水果种类
SELECT f1.f_id,f1.f_name
FROM fruits AS f1,fruits AS f2
WHERE f1.s_id = f2.s_id
AND f2.f_id = 'a1';

-- 外连接  
-- LEFT JOIN
-- RIGHT JOIN

-- 创建演示表
CREATE TABLE `orders` (
  `o_num` int(4) NOT NULL,
  `o_date` datetime NOT NULL,
  `c_id` int(4) NOT NULL,
  PRIMARY KEY (`o_num`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- LEFT JOIN :返回左表中的所有记录 和 右表中连接字符相等的记录
-- 查询所有客户,包括没有订单的客户(即:customers 中order_id为 NULL的客户
SELECT customers.c_id,orders.o_num
FROM customers LEFT JOIN orders
ON customers.c_id = orders.c_id;

-- RIGHT JOIN :同上,右表所有记录+连接字符相等记录

-- LIKE
SELECT * FROM fruits WHERE f_name LIKE '%app%';

-- 使用正则表达式
-- ^ , $ , . , * , + , <字符串> , [字符集合] , [^] , 字符串{n,} ,字符串{n,m}
-- 用法:
SELECT * FROM fruits WHERE f_name REGEXP '^a';

SELECT * FROM fruits WHERE f_name REGEXP 'a$';
 
-- *:匹配前面的字符任意多次          以b开头,且b后面出现字母a
SELECT * FROM fruits WHERE f_name REGEXP '^ba*';

-- 其他都是类似的


-- EXISTS关键字的子查询
-- 查询suppliers表中是否存在s_id=107的供应商,如果存在,则查询fruits表中的记录
SELECT * 
FROM fruits
WHERE EXISTS
(SELECT s_name FROM suppliers WHERE s_id = 107);


-- 查询suppliers表中是否存在s_id=107的供应商,如果存在,则查询fruits表中f_price>10.20的记录
SELECT * 
FROM fruits
WHERE f_price > 10.20 AND EXISTS
(SELECT s_name FROM suppliers WHERE s_id = 107);


-- 带IN关键字的子查询,
-- 在orderitems表中查询f_id为c0的订单号,并根据订单号查询具有订单号的客户c_id
SELECT c_id 
FROM orders 
WHERE o_num IN
(SELECT o_num FROM orderitems WHERE f_id = 'c0');




-- p230练习:
-- 1.建表

CREATE TABLE dept
(
		d_no INT NOT NULL PRIMARY KEY auto_increment,  -- 部门编号
		d_name VARCHAR(50) NOT NULL, -- 部门名称
		d_location VARCHAR(50) -- 部门地址
);

CREATE TABLE emp
(
		e_no INT(11) NOT NULL PRIMARY KEY,
		e_name VARCHAR(50) NOT NULL,
		e_gender CHAR(2),
		dept_no INT(11) NOT NULL,   -- 外键,部门编号
		e_job VARCHAR(50) NOT NULL,
		e_salary INT(11) NOT NULL,
		hireDate DATE NOT NULL,
		CONSTRAINT dno_fk FOREIGN KEY(dept_no) REFERENCES dept(d_no)
);

-- 插入数据
INSERT INTO dept
VALUES (10,'Accounting','Shanghai'),
(20,'Research','Beijing'),
(30,'Sales','Shenzhen'),
(40,'Operations','Fujian');

INSERT into emp
VALUES
(1001,'小白1','m',20,'前台',800,'2005-11-20'),
(1002,'小白2','w',30,'后台',800,'2001-11-20'),
(1003,'小白3','w',20,'老板',1800,'2000-11-20'),
(1004,'小白4','m',10,'前台',1200,'2001-11-20'),
(1005,'小白5','w',20,'后台',2800,'1998-11-20'),
(1006,'小白6','m',40,'后台',4800,'2005-11-20'),
(1007,'小白7','m',20,'审计',1800,'1995-11-20'),
(1008,'小白8','w',30,'前台',700,'2015-11-20'),
(1009,'小白9','m',40,'审计',300,'2005-11-20'),
(1010,'小白10','w',20,'前台',900,'2010-11-20'),
(1011,'小白11','w',20,'经理',3800,'1990-11-20'),
(1012,'小白12','m',30,'前台',800,'2005-11-20');

-- 1.在emp表查询所有记录的e_no,e_name,e_salary
SELECT e_no,e_name,e_salary
FROM emp;

-- 2.在emp表,查询dept_no=10和20的所有记录
SELECT * 
FROM emp
WHERE dept_no in(10,20);

-- 3.emp,查询工资在800-2500
SELECT *
FROM emp
WHERE e_salary BETWEEN 800 and 2500;

-- 4,emp表 查询部门编号为20的部门的员工信息
SELECT *
FROM emp
WHERE dept_no = 20;

-- 5.查询每个部门最高工资的员工信息
SELECT e_name,dept_no,MAX(e_salary)
FROM emp
GROUP BY dept_no;

-- 6.查询小白6所在部门和部门所在地
SELECT d_name,d_location 
FROM emp,dept
WHERE emp.dept_no = dept.d_no AND emp.e_name = '小白6';

-- 7.使用连接查询,查询所有员工的部门和部门信息
SELECT *
FROM emp,dept
WHERE emp.dept_no = dept.d_no;

-- 8.emp表,计算每个部门有多少员工
SELECT dept_no,count(*) AS total
FROM emp
GROUP BY dept_no;

-- 9.emp表,计算不同类型职工的总工资数
SELECT dept_no,sum(e_salary)
FROM emp
GROUP BY dept_no;

-- 10.emp表,计算不同部门的平均工资
SELECT dept_no,AVG(e_salary)
FROM emp
GROUP BY dept_no;

-- 11.emp表,查询工资低于1500的员工
SELECT *
FROM emp
WHERE e_salary <1500;

-- 12.emp表,将查询记录先按部门降序排列,再按员工工资降序排序
SELECT e_name,dept_no,e_salary
FROM emp
ORDER BY dept_no,e_salary DESC;

-- 13.emp表,查询员工姓名以‘白’结尾的员工信息
SELECT * 
FROM emp
WHERE e_name REGEXP '白$';

-- 14.emp表,查询到目前为止,工龄大于10年的员工信息
SELECT *
FROM emp
WHERE (YEAR(CURDATE())-YEAR(hireDate)) > 10;

-- 15.emp表,计算所有女员工的工龄
SELECT e_name,(YEAR(CURDATE())-YEAR(hireDate)) as gonli
FROM emp
WHERE e_gender = 'w';

-- 16.emp表,查询从第3条记录开始到第7条
SELECT *
FROM emp
LIMIT 2,5;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值