数据库(sql语句)

数据的操作

1、插入数据,
1.1单条记录插入:
insert into 表名(字段1, 字段2, 字段3, ……)
values(值1,值2,值3,…);
1.2 批量记录插入:
insert into 表名(字段1, 字段2, 字段3, ……)
values(值11,值21,值31,…),
(值12,值22,值32,…),
……;
2、更新数据。
2.1 更新所有数据
update 表名 set 字段1=值1,字段2=值2, 字段3=值
2.2更新特定数据记录:
update 表名set 字段1=值1,字段2=值2, 字段3=值3,
……where 条件;

3、删除数据。
3.1 删除特定数据
delete from表名 where 条件;
3.2 删除所有数据
delete from 表名;

单表数据记录查询

1、简单数据查询,
1.1 查询所有字段 select * from 表名
1.2 查询指定字段 select 字段 …… from 表名
1.3 避免重复数据查询 select distinct 字段… from 表名
1.4 实现数字四则运算数据查询(+,-,*,/,%)
select 字段 运算符 运算符操作数… from 表名
1.5设置显示格式数据查询 CONCAT()
select 字段 [as] 字符串 from 表名
select CONCAT(字段 字符串 … ) from 表名
例:select CONCAT(name, ‘––>’, score) from student

2、条件数据记录查询
select 字段 …… from 表名 where 条件
mysql 支持的比较运算符和逻辑运算符

 >,<,=,!=,>=,<=,         AND(&&) ,OR(||),XOR(异或),NOT(!)
2.1 单条件数据查询:
      select 字段 …... from 表名 where 条件
2.2 多条件数据查询:
      select 字段 …... from 表名 where 条件1 AND 条件2....
2.3  带 between and 关键字的范围查询;
       select 字段 …... from 表名 where字段 between 值1 AND 值2
2.4  不符合范围的数据记录查询
      select 字段 …... from 表名 where字段 not between 值1 AND 值2
2.5  带 IS NULL的关键字的空值查询
      select 字段 …... from 表名 where 字段名 is null;
2.6  非空记录查询
      select 字段 …... from 表名 where 字段名 is not null;
2.7 带 IN 关键字的集合查询:
      select 字段 …... from 表名 where 字段名 in (1,2,...)
2.8 不在集合中数据记录查询:
      select 字段 …... from 表名 where 字段名 not in (1,2,...)
2.9  带 LIKE 关键字的模糊查询;
       select 字段 …... from 表名 where 字段名 like 值1

     LIKE 关键字支持的通配符 
    
   “_” : 通配单个字符; 

  “%:   通配任意字符,可以是0个字符,1个字符,或多个字符
  1. 排序查询:
    select 字段 …… from 表名 ORDER BY 字段名 ASC | DESC
    ASC 表明升序 DESC 表明降序
  2. 分组查询:
    select 字段 …… from 表名 [WHERE 条件] group BY 字段名
    分组后结果再进行条件过滤则必须使用having 字句:
    select 字段 …… from 表名 [WHERE 条件] group BY 字段名 having 条件

说明:
分组查询(GROUP BY)一般和聚合函数(统计函数)一起使用,如果查询的字段出现在
GROUP BY后,却没有包含在聚合函数中,SQL语句很有可能会报错.

例子: 1.    通过部门分组后,获取每个部门的人数,
                       select count(name) from fruit group by dept;
            2.  还可以在分组后设置条件过滤,要求统计部门人数时,该部门人数要>1
                       select count(name) from fruit group by dept having count(name)>1;
            3.  如果想获取分组后部门人员组成,可使用 group_concat函数
                      select group_concat(name) from fruit group by dept;
  1. 排序查询:
    select 字段 …… from 表名 ORDER BY 字段名 ASC | DESC
    ASC 表明升序 DESC 表明降序
  2. 分组查询:
    select 字段 …… from 表名 [WHERE 条件] group BY 字段名
    分组后结果再进行条件过滤则必须使用having 字句:
    select 字段 …… from 表名 [WHERE 条件] group BY 字段名 having 条件

说明:
分组查询(GROUP BY)一般和聚合函数(统计函数)一起使用,如果查询的字段出现在
GROUP BY后,却没有包含在聚合函数中,SQL语句很有可能会报错.

例子: 1.    通过部门分组后,获取每个部门的人数,
                       select count(name) from fruit group by dept;
            2.  还可以在分组后设置条件过滤,要求统计部门人数时,该部门人数要>1
                       select count(name) from fruit group by dept having count(name)>1;
            3.  如果想获取分组后部门人员组成,可使用 group_concat函数
                      select group_concat(name) from fruit group by dept;
  1. 聚合函数查询:
    COUNT函数:统计记录行的总数
    select count(字段名) from 表名
    注意:如果字段名为 *,计算表中的总行数,不管某字段是否为NULL
    如果指定了具体字段名,会忽略空值的行

    SUM函数:统计某列数据的和
    select sum(字段名) from 表名
    AVG函数:统计某列数据的平均值
    select avg(字段名) from 表名
    MAX函数:统计某列数据的最大值
    select max(字段名) from 表名
    MIN函数:统计某列数据的最小值
    select min(字段名) from 表名

多表连接查询

  1. 内连接:
    又称为简单连接,或者自然连接,是一种常见的连接查询.内连接使
    用比较运算符,对两个表中的数据,进行比较,并列出与连接条件匹
    配的数据行,组合成新的记录。
    在内连接查询中,只有满足条件的记录,才会出现在查询结果中.
    简单理解:返回表1和表2同时满足条件的记录。

    语法格式
    SELECT 查询字段 FROM 表1 [INNER] JOIN 表2 ON
    表1.关系字段=表2.关系字段;

    例子:两个表联合查询
    select 字段名… FROM 表1 INNER JOIN 表2 ON 条件;
    多个表查询时,可使用:
    select 字段名… FROM 表1 INNER JOIN 表2 ON 条件
    INNER JOIN 表3 ON 条件;

  2. 外连接:
    内连接查询,返回的结果,只包含符合查询条件和连接条件的数据
    有时需要返回的查询结果,不仅包含符合条件的数据,而且,包括左
    表和右表中的所有数据,此时,需要使用外连接.

    2.1 左外连接
    以左边的表为主,在右边的表中找到所有满足条件的元素,并 把他们连接起来,如果没有对应的元素,则在相应位置上的值
    为null。
    select 字段名… FROM 表1 LEFT JOIN 表2 ON 条件;

    2.2 右外连接
    与左外连接相反,以右边的表为主,在左边的表中找到所有满
    足条件的元素,并把他们连接起来,如果没有对应的元素,则
    在相应位置上的值为null。
    select 字段名… FROM 表1 RIGHT JOIN 表2 ON 条件;

SQL语句的执行顺序

在这里插入图片描述

子查询

子查询是指一个查询语句嵌套在另一个查询语句内部的查询,在select子句中先计算子查询,子查询结果作为外层另一个查询的条件,查询可以基于一个表或者多个表.
子查询中常用的操作符有 ANY(SOME),ALL,IN,EXISTS,子查询可以添加到select,update,delete语句中,而且可以进行多层嵌套。子查询也可以使用比较运算符如“<,>,<=,>=,!=,=”等。

  1. 带有ANY(SOME)关键字的子查询:
    它允许创建一个表达式,对子查询的返回值列表,进行比较,只要满
    足内层子查询中的,任意一个比较条件,就返回一个结果作为外层查
    询条件。

例子:

select 字段名… FROM 表 where 字段>ANY(select 字段名… FROM 表);

  1. 带有ALL关键字的子查询:
    ALL与ANY不同,表示同时满足所有内层查询的条件,

例子:
select 字段名… FROM 表where 字段>ALL(select 字段名… FROM 表);

  1. 带有EXISTS关键字的子查询:
    EXISTS后面的参数,可以是任意一个子查询,这个子查询的作用相当
    于测试,它不产生任何数据,只返回TRUE或FALSE.当返回值为TRUE
    时,外层的查询才会执行,

例子:
select 字段名… FROM 表where EXISTS (select 字段… FROM 表);

只有在蓝色部分的子查询存在结果时,才去执行外层红色部分的查询
4. 带有IN关键字的子查询:

使用IN关键字,进行子查询时,内层查询语句返回一个数据列,这个
数据列中的值,将供外层查询语句进行比较操作

例子:
select 字段名… FROM 表where 字段IN (select 字段名… FROM 表);

  1. 带有比较运算符的子查询:
    子查询中,可以使用比较运算符,比如<、>、<=、>=、=、!=等

例子:
select 字段名… FROM 表where 字段= (select 字段… FROM 表);

请注意如果用 = 比较运算符,子查询的结果往往是唯一的。

数据库备份和加载

  1. 备份数据库:
    终端输入:
    mysqldump -u root -p 需备份的数据库名 >备份的目的路径

  2. 将备份文件拷贝到目标主机:

  3. 目标主机登陆mysql,创建新的数据库:
    create database 新的数据库名称

4 导入备份数据:
第一种方法: 终端输入:
mysql -u root -p 新建的数据库名 < 备份文件路径

   第二种方法: mysql中执行:
         mysql>use 新建的数据库名;
         mysql> source 备份文件路径;

案例

#########  多表查询:内连接, 外连接 #################

# 创建部门表
CREATE TABLE dept(
	id INT PRIMARY KEY AUTO_INCREMENT,
	NAME VARCHAR(20)
);
INSERT INTO dept (NAME) VALUES ('开发部'),('市场部'),('财务部');

SHOW CREATE TABLE dept;
# 创建员工表
CREATE TABLE emp (
	id INT PRIMARY KEY AUTO_INCREMENT,
	NAME VARCHAR(20),
	gender CHAR(1), -- 性别
	salary DOUBLE, -- 工资
	join_date DATE, -- 入职日期
	dept_id INT,
	FOREIGN KEY (dept_id) REFERENCES dept(id) -- 外键,关联部门表(部门表的主键)
);
INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('孙悟空','男',7200,'2013-02-24',1);
INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('猪八戒','男',3600,'2010-12-02',2);
INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('唐僧','男',9000,'2008-08-08',2);
INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('白骨精','女',5000,'2015-10-07',3);
INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('蜘蛛精','女',4500,'2011-03-14',1);

/*
外键约束:限制从表插入数据的合理型
如果没有外键约束,不影响业务逻辑上的数据关联关系
*/

# 笛卡尔积查询 --- 导致数据混乱
SELECT * FROM emp, dept;

/*
多表查询分析步骤:
	1.查询的数据在哪些表上(涉及那几张表)
	2.这些表的关联关系
	3.还有哪些筛选条件
	4.最后再考虑查询哪些字段
*/

# 多表-- 内连接
# 查询所有员工及其所属部门信息
# 内连接 -- 隐式内连接:where
SELECT * FROM emp, dept WHERE emp.`dept_id` = dept.`id`;
# 内连接 -- 显示内链接:inner join ... on
SELECT * FROM emp INNER JOIN dept ON emp.`dept_id` = dept.`id`;
SELECT emp.`id`, emp.name emp_name, gender, salary, dept.name  dept_name FROM emp INNER JOIN dept ON emp.`dept_id` = dept.`id`;

# 查询猪八戒是那个部门的
SELECT 
  emp.`id`,
  emp.name emp_name,
  gender,
  salary,
  dept.name dept_name 
FROM
  emp 
  INNER JOIN dept 
    ON emp.`dept_id` = dept.`id`
  WHERE emp.`NAME` = '猪八戒';
  
# 方式二 
SELECT * FROM emp WHERE NAME='猪八戒';
SELECT * FROM dept;

SELECT t1.*, t2.* FROM (SELECT * FROM emp WHERE NAME='猪八戒') t1
 INNER JOIN (SELECT * FROM dept) t2 
 ON t1.dept_id = t2.id;
 
# 外连接: 左外连接(left [outer] join...on ), 右外链接(right [outer] join...on )
# 左外和右外可以互相转换,重点掌握左外连接
# 外连接的查询: 主表和从表数据没有管理关系,但要将主要业务逻辑的表数据表数据全部查询出来

# 左外查询:将左表中的数据全部查询出来
# 查询所有员工信息,刚入职没有分配部门的员工也要查询出来
SELECT * FROM emp LEFT JOIN dept ON emp.`dept_id` = dept.`id`;
# 右外查询: 将右表中的数据全部查询出来
SELECT * FROM dept RIGHT JOIN emp ON emp.`dept_id` = dept.`id`;

# 查询所有部门下的员工信息,新成立的部门下没有员工也要查询出来
SELECT * FROM emp RIGHT JOIN dept ON emp.`dept_id` = dept.`id`;
SELECT * FROM dept  LEFT JOIN emp ON emp.`dept_id` = dept.`id`;

# 子查询:当前sql需要使用另外一个sql语句查询作为条件,这样的sql语句称为子查询

/*
子查询的思路:
	1.子查询的条件是一个单行单列: 使用where的条件判断语句(=,!=, >, >=, < , <=)
	2.子查询的条件是多行单列: in , not in, (any, all)
	3.子查询的条件是多行多列: 当作一张临时表看待
*/


# 1.子查询的条件是一个单行单列: 使用where的条件判断语句(=!=, >, >=, < , <=)

# 需求:查询姓名是唐僧员工所属部门 
-- 步骤1: select dept_id from emp where name='唐僧';
-- 步骤2: select * from dept where id = 2;
SELECT * FROM dept WHERE id = (SELECT dept_id FROM emp WHERE NAME='唐僧');

# 需求:查询姓名是唐僧员工的信息及其所属部门 
SELECT * FROM dept, emp WHERE dept.`id` = emp.`dept_id` AND emp.`NAME`='唐僧';

# 需求:查询工资大于5000的员工来自那个部门
SELECT * FROM (SELECT * FROM emp WHERE salary>5000) t1 LEFT JOIN dept ON t1.dept_id = dept.id;
/*
1. 查询工资大于5000的员工
2. 查询id是1,3,6的员工来自那个部门
*/
# 1. 查询工资大于5000的员工
SELECT * FROM emp WHERE salary>5000;

SELECT dept_id FROM emp WHERE salary>5000;
# 2.子查询的条件是多行单列: in , not in
SELECT dept_id FROM emp WHERE salary>5000;
SELECT * FROM dept WHERE id IN (SELECT dept_id FROM emp WHERE salary>5000);
-- select * from dept where id=1 or id=2 or id=null;
# 3.子查询的条件是多行多列----当作一张临时表看待
SELECT * FROM emp WHERE salary>5000;
-- 查询工资大于5000的员工信息及其所属部门,如果有员工没有分配部门也要查出来
SELECT * FROM (SELECT * FROM emp WHERE salary>5000) t1 LEFT JOIN dept ON t1.dept_id = dept.id;
-- 查询工资大于5000的员工信息及其所属部门
SELECT dept.* FROM (SELECT * FROM emp WHERE salary>5000) t1 INNER JOIN dept ON t1.dept_id = dept.id;

-- 子查询练习:
# 需求:查询大于平均工资的所有员工信息
-- 1. 查询平均工资
SELECT AVG(salary) FROM emp;
-- 2. 根据平均工资查询员工表
SELECT * FROM emp WHERE salary > 5883;
-- 最终的子查询语句
SELECT * FROM emp WHERE salary > (SELECT AVG(salary) FROM emp);

# 需求:查询工资低于平均工资的员工并且员工的入职时间早于2011年
SELECT * FROM emp WHERE salary < (SELECT AVG(salary) FROM emp) AND join_date < '2011-01-01';

# 需求:查询工资大于平均工资的员工并且该员工属于市场部门
-- 方式1
SELECT * FROM 
(SELECT * FROM emp WHERE salary > (SELECT AVG(salary) FROM emp)) t1,
dept
WHERE t1.dept_id = dept.id AND dept.`NAME`='市场部';
 
-- 方式2 : 先查询员工和部门的对应关系表,然后在表中筛选需要的数据
SELECT t1.*  FROM
 (SELECT emp.*, dept.`NAME` 部门  FROM emp, dept WHERE emp.`dept_id` = dept.`id`) t1
  WHERE t1.salary > (SELECT AVG(salary) FROM emp) AND t1.部门='市场部';
  
-- 方式3 : 先查询名称是市场部门的id, 再根据这个id,和平均工资筛选员工表
SELECT emp.*, (SELECT NAME FROM dept WHERE id = emp.`dept_id`)
FROM emp 
WHERE salary>(SELECT AVG(salary) FROM emp) 
AND emp.`dept_id`=(SELECT id FROM dept WHERE NAME='市场部')

# 子查询: any, all, 
# any :表示满足子查询结果中的任意一个
SELECT * FROM emp WHERE salary > ANY(SELECT salary FROM emp WHERE salary >=4500);
SELECT * FROM emp WHERE salary < ANY(SELECT salary FROM emp WHERE salary >=4500);
SELECT salary FROM emp WHERE salary >=4500;
SELECT * FROM emp;

# all: 表示满足子查询结果中的所有
SELECT * FROM emp WHERE salary > ALL(SELECT salary FROM emp WHERE salary >=4500);
SELECT * FROM emp WHERE salary < ALL(SELECT salary FROM emp WHERE salary >=4500);

/*
 EXISTS : 相当于开关,当EXISTS后面小括号内查询有结果表示真,当没有结果表示假
	如果为真,就执行第二步查询语句
	如果为假,就不执行第二步查询语句
 */
SELECT * FROM emp WHERE  EXISTS(SELECT salary FROM emp WHERE salary >=14500);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值