MySQL学习(1)基础详解

文章目录

  • 1、了解SQL
  • 2、使用MySQL
  • 3、创建数据库和操纵表
  • 4、检索数据
  • 5、创建计算字段
  • 6、使用数据处理函数
  • 7、分组数据
  • 8、使用子查询
  • 9、插入数据、更新和删除数据
  • 10、多表查询

1、了解SQL

什么是数据库?

  • 数据库是数据存储的仓库,用于存储和管理数据;
  • 常见数据库产品:
  • Oracle:oracle公司,大型的关系型数据库,收费的
  • DB2:IBM公司,大型的关系型数据库,收费的
  • MySQL:MySQL公司,中小型关系型数据库,免费的;后来被oracle收购,MySQL之后收费(社区版,旗舰版);
  • Sql Server:微软公司,中小型关系型数据库,收费的
  • Sqllite:安卓系统内置数据库,微型关系型数据库,免费的
  • NoSql系列数据库:not only sql,非关系型数据库;

什么是SQL?

  • SQL:结构化查询语言

概念:通过sql语言可以操作所有的关系型数据库。每种数据库之间会存在差异,称为 “方言”;

  • SQL的分类:
  • DDL(Data Definition Language):数据定义语言,用来定义数据库对象:库、表、列等;
  • DML(Data Manipulation Language):数据操作语言,用来定义数据库记录(增、删、改)
  • DCL(Data Control Language):数据控制语言,用来定义访问权限和安全级别;
  • DQL(Data Query Language):数据查询语言,用来查询记录(数据)。

数据库管理系统(DBMS)

  • 按照一定的数据模型组织数据,管理数据库。数据库应用系统通过DBMS提供的接口操作数据库,数据库管理员(DBA)通过DBMS提供的界面管理、操作数据库。
  • 数据、数据库、数据库管理系统与操作数据库的应用程序,加上支持他们的硬件平台、软件平台与数据库有关人员一起构成了一个完整的数据库管理系统

关系模型

  • 关系模型是目前应用最多、最为重要的一种数据模型。关系模型建立在严格的数学概念基础上,已二维表的形式组织数据库中的数据,二维表由行与列组成。从用户观点来看,关系模型是由一组关系组成的,关系之间通过公共属性产生联系。每个关系的数据是一个规范化的二维表,所以一个关系数据库就是由若干个表组成的。

在这里插入图片描述

  • 按照关系模型组织数据表达方式简洁、直观、插入、删除、修改操作方便,而按层次、网状模型组织数据表达方式操作比较复杂,因此关系型数据库管理系统(RDBMS)成为主流。

2、使用MySQL

什么是MySQL

  • 如上所述,数据的所有存储、检索、管理和处理实际上是由数据库软件——DBMS(数据库管理系统)完成的,MySQL是一种DBMS,即它是一种数据库软件;
  • MySQL已经存在很久了,为什么有那么多人使用它?

1、成本:MySQL是开放源码的,一般可以免费使用;
2、性能:MySQL执行很快;
3、可信赖:某些非常重要的公司、站点使用它;
4、简单:MySQL很容易安装何使用;

客户机-服务器软件

  • DBMS可分为两类,一类是基于共享文件系统的DBMS,另一类为基于客户机-服务器的DBMS,前者用于桌面用途,通常不用于高端或更关键的应用;
  • MySQL、Oracle以及Microsoft SQL Server等数据库是基于客户机-服务器的数据库,客户机-服务器应用分为两个不同的部分;

服务器部分是负责所有数据访问和处理的一个软件,这个软件运行在称为数据库服务器的计算机上;

  • 与数据文件打交道的只有服务器软件,关于数据、数据添加、删除和数据更新的请求都由服务器软件完成。这些请求来自客户及软件的计算机;

客户机是与用户打交道的软件,与服务器可能安装在两个不同的计算机或者一个计算机上,为进行数据库交互,客户机与服务器之间进行通信;

  • 服务器的软件为MySQL DBMS,客户机可以是MySQL提供的工具、脚本语言(Perl)、Web应用开发语言(ASP、JSP、PHP等)、程序设计语言(C、C++、Java);

MySQL安装以及命令行

  • MySQL8安装详解

  • 关于MySQL服务的命令:

1.手动关闭:我的电脑-->右键-->管理
2.cmd-->services.msc,打开服务面板
3.登陆数据库:cmd-->mysql -uroot -p你自己的密码
4.服务:系统后台进程

  • 启动服务:net start mysql
  • 停止服务:net stop mysql
  • 删除服务:sc delete mysql

5.修改mysql的密码步骤:

  • 停止mysql服务:运行输入services.msc,手动停止mysql服务,或者 cmd – net stop mysql
  • 在cmd下 输入 mysqld –skip-grant-tables 启动服务器,光标不动 (不要关闭该窗口)
  • 新打开cmd 输入:
    mysql -u root -p 旧密码
    use mysql;update user set password=password'123456') WHERE User='root';
  • 关闭两个cmd窗口 在任务管理器结束mysqld 进程;
  • 在服务管理页面 重启mysql 服务

3、创建数据库和操纵表

  • DDL:建库,建表,删库,删表;
  • 查询所有的数据库:
show databases;
  • 创建数据库:
create database mytestdb;
  • 删除一个数据库:
drop database mytestdb;
  • 建表:
create table 表名列名 类型长度), 列名2 类型2长度)...)
-- 在这个mydb 库下去建表create table teachername varchar10),age int,sex char1),sal double5,2));

建表之前先切换库:use mydb; -- 使用这个库

  • 查看该库下的所有表:
show tables;
  • 删除表:
drop table 表名  -- 例如: drop table student;
  • 查询表结构:
desc 表名;

describe语句:MySQL支持使用describe作为show columns from的一种快捷方式;

  • 修改表 alter(对表头进行增删改)
-- 往表中增加一个字段 add 字段名 数据类型)
alter table teacher add sex char1);
-- 删除一个字段 drop 字段名
alter table teacher drop sex;
-- 修改字段的数据类型 modify 旧字段名 新类型
alter table teacher modify tname char10);
-- 修改字段名称  change 旧列名 新列名 char10);
alter table teacher change tname username char10);
-- 使用 change 也能修改列的数据类型
alter table teacher change username username varchar10);
--修改表名 alter table 旧表名 rename to 新表名;
alter table teacher rename to dog;

4、检索数据

查询表中的数据 select

-- 查询表中所有的数据
select * from 表名;

一般尽量减少使用通配符,因为这样会降低性能;

-- 查询个别字段的值
select username,tage from 表名;

使用select查询出来的数据显示与插入的顺序有可能不同,因为你没有明确排序查询结果,只要返回相同数目的行,就是正常的;

  • 去重:一般如果select语句返回匹配的所有行,但是你不想要每个值每次都出现,解决办法是使用distintct关键字;
select distinct vned_id form products;
  • 限制结果:select 语句返回所有匹配的行,他们可能是指定表中的每个行,为了返回第一行或前几行,可使用limit子句;
select prod_name from products limit 5,5;

limit 5,5指示MySQL返回从行5开始的5行,第一个数字为起始位置,第二个数字为要检索的行数;带一个值的limit总是从第一行开始,给出的数为返回的行数;

【使用SQL语句的注意事项:】

1、结束SQL语句以分号分隔;
2、SQL语句不区分大小写,一般来说,SQL的关键字使用大写;
3、SQL中的空格一般会被忽略;

排序检索数据

  • 未经过排序的数据一般将以它在底层表中出现的顺序显示,这可能是数据最初添加到表中的顺序;但是如果数据后来进行过更新或删除,则顺序将会受到MySQL重用回收存储空间的影响;
  • 排序:为了明确的排序用select语句检索出的数据,可使用order by子句,order by子句取一个或多个列的名字,查询所有员工信息按照工资升序排列:order by 工资
-- ASC 升序  DESC 降序
select * from emp order by sal asc;
select * from emp order by  ename desc;
-- 可以定义第二排序条件
select * from emp order by sal asc,comm desc;

在字典排序顺序中,A被视为与a相同,这是MySQL的默认行为;

  • DESC关键字以降序排列,ASC则以升序排列(默认就是以ASC升序排列);

过滤数据

  • 条件查询 where ,下面是他的操作符:
    在这里插入图片描述
BETWEENAND;  在什么范围之间
INset)IS NULL;为空
IS NOT NULL 不为空
AND; 并且
OR;   或者
NOT;非
-- 建表语句
CREATE TABLE empempno INT,ename VARCHAR50),job VARCHAR50),mgr INT,hiredate DATE,sal DECIMAL7,2),comm decimal7,2),deptno INT
) ;
-- 查询工资 大于 500 的员工信息
select * from emp where sal>1000;-- 查询工资 大于 等于1000 小于等于2000 的员工信息select * from emp where sal>=1000 and sal<=2000; -- 查询工资大于1000 或奖金 大于100的select * from emp where sal>=1000 or comm>=100;-- 查询工资 大于 等于1000 小于等于2000 的员工信息 BETWEEN…AND:在什么范围之间select * from emp where sal between 1000 and 2000;-- 查询奖金是 300 500 的人
select * from emp where comm=300 or comm=500;select * from emp where comm in300,500);-- 查询奖金为null
-- null 值 不能用 = != 去判别
select * from emp where comm is null;-- 查询奖金不为 null的
select * from emp where comm is not null;-- 字段可以进行数学运算
select ename,sal,comm from emp;select ename,sal,comm,sal*12 from emp;-- 可以给字段起个别 as  注意 as 可以省略不写select ename as '姓名',sal as '工资',comm as '奖金',sal*12 as '年薪' from emp;
  • and和or操作符

为了通过不止一个列进行过滤,可使用and操作符给where子句附加条件

select pro_id,pro_price,prod_name from products where vend_id =1003 and prod_price<=10;

or操作符的意思是匹配任一条件的行;

select pro_id,pro_price,prod_name from products where vend_id =1003 or  vend_id =1002;

计算次序:MySQL中的and和or操作符组合建立了一个where子句,and在计算次序中优先级要高于or;可以使用圆括号明确地分组相应的操作符,消除歧义;

模糊查询 like

通配符是用来匹配值的一部分的特殊字符;SQL中使用like关键字配合通配符构成搜索子句;
搜索模式:由字面值、通配符或两者组合构成的搜索条件;

%匹配任意字符,还可以匹配0个字符;
_匹配单个任意字符,不能匹配0个字符;

使用通配符的技巧:

1、不要过度地使用通配符;
2、在确实需要使用通配符时,不要把他们用在搜索模式的开始处;

-- 模糊查询使用过的通配符  _ 匹配单个任意字符  % 匹配多个任意字符
-- 我要查询姓名包含A的人
select * from emp where ename like '%A%';--查询姓名是A开头的人
select * from emp where ename like 'A%';
-- 查询姓名是K结尾的人
select * from emp where ename like '%K';-- 查询第二个字符是M的人
select * from emp where ename like '_M%';
--查询这个名字是5个字符组成的人呢
select * from emp where ename like '_____';
select * from emp where ename like 'SMITH';    

用正则表达式进行搜索

  • 随着过滤条件的复杂性增加,where子句本身的复杂性也有必要增加,正则表达式是用来匹配文本的特殊的串(字符集合);
select prod_name from products where prod_name regexp '.000' order by prod_name;
  • 匹配几个字符之一:
regexp '[123]'
regexp '[^123]'-----------匹配除了这些字符外的任何字符
  • 匹配范围:可以使用-来定义一个范围
regexp '[0-9]'
  • 匹配特殊字符:必须使用转义
regexp '[\\.]'-------表示查找.
regexp '[\\-]'-------表示查找-
  • 匹配字符类:查找出你经常使用的数字、所有字母或所有数字字母字符等的匹配

在这里插入图片描述

  • 匹配多个实例:
    在这里插入图片描述
  • 定位符:为了匹配特定位置的文本
    在这里插入图片描述

5、创建计算字段

  • 存储在数据库表中的数据一般不是应用程序所需要的格式,下面举几个例子:
    在这里插入图片描述

客户机与服务器的格式:可在SQL语句内完成的许多转换和格式化工作都可以直接在客户机应用程序内完成,但一般来说,在数据库服务器上完成这些操作比在客户机中完成要快得多,因为DBMS是设计来快速有效的完成这种处理的;

  • 使用别名:使用关键字as给当前列或者当前的表起一个临时的名字,并不会改变原有列的名字以及表;
  • 执行算术运算:
--查询年薪 并加上奖金  null  值参与运算结果 null
select ename,sal,comm,sal*12 + comm from emp;
-- 如果奖金是null值 我们想要当0来处理 ifnull)
select ename,sal,comm,sal*12+ifnullcomm,0) from emp;
-- 聚合函数  null值不参与  countcomm)
select countcomm) as total from emp;

6、使用数据处理函数

  • 与其他大多是计算机语言一样,SQL支持利用函数处理数据,函数一般都是在数据上执行的,他给数据的转换和处理提供了方便;

  • 常见的文本处理函数有:
    在这里插入图片描述
    在这里插入图片描述

  • 日期和时间处理函数:日期和时间采用相应的数据类型和特殊的格式存储,以便能快速和有效地排序或过滤,并且节省物理存储空间;常见的日期和时间处理函数有:
    在这里插入图片描述

  • 数值处理函数:数值处理函数仅处理数值数据;
    在这里插入图片描述

  • MAX)、MIN)

select maxsal) as zdz from emp;select minsal) as zdz from emp;
  • avg) 平均值、COUNT)
select avgsal) as zdz from emp;select sumsal)/count*) from emp;
  • sum 求和
select sumsal) from emp;

7、分组数据

  • 分组查询:group by,一般配合聚合函数使用查出的数据才有意义
  • 查询的字段:

1、分组字段本身
2、聚合函数

  • 比如我按部分编号分组,有三个部门。然后我求每个部门的平均工资,那展示出来的数据应该有三条,例如:
select 部门编号,AVG工资) from student group by 部门编号;
  • 例如查询每个部门的部门编号,已经每个部门工资大于1500的人数:
select 部门编号, count*) from student where 工资>1500 group by 部门编号;

注意这里的 where 是对分组前的条件限定,也就是说不满足条件的,不参与分组;

  • where 和 having
  • where:在分组之前对条件进行限定。不满足条件,就不会参与分组
  • having:在分组之后,对结果集的筛选
  • 我要查询各个部门平均工资大于2000的部门
select 部门编号,avg工资) from student group by 部门编号 having avg工资)>2000;
  • 例如我要查询各个部门员工工资大于1500 的平均工资并且平均工资大于2000的部门,上面这句话怎么理解呢? 首先查询各个部门,那肯定要按部门编号分组,分组前的条件限定是:员工工资大于1500的才参与分组,计算出平均工资 然后对结果再进行筛选,筛选出平均工资大于2000的部门:
select 部门编号,avg工资) from student group by 部门编号 where avg工资)>1500 having  avg工资)>2000;
  • 分页查询:limit

limit 0,5 开始的记录索引,每一页显示的条数,索引从0开始
开始的记录索引 = 页码-1)*每一页显示的条数

  • 例如:我显示第一页,每页5条记录
select * from student limit 0,5 ;  这是第一页 5 条记录
select * from student limit 5,5 ; 这是第二页 5条记录
select * from student limit 10,5 这是第三页 5条记录
  • oracle:rownum 分页方言
  • sqlserver:top 分页方言
  • 注意:select子句的顺序是:select、from、where、group by、having、order by、limit

8、使用子查询

  • select语句是SQL的查询,在这之前我们看到的查询都是简单的select查询,即从单个数据库表中检索数据的单条语句;SQL还允许创建子查询,是一种嵌套在其他 SQL 查询的 WHERE 子句中的查询。
  • 子查询用于为主查询返回其所需数据,或者对检索数据进行进一步的限制。
  • 子查询可以在SELECT、INSERT、UPDATE 和 DELETE 语句中,同=、<、>、>=、<=、IN、BETWEEN等运算符一起使用。
  • 使用子查询必须遵循以下几个规则:

子查询必须括在圆括号中。
子查询的 SELECT 子句中只能有一个列,除非主查询中有多个列,用于与子查询选中的列相比较。
子查询不能使用ORDER BY,不过主查询可以。在子查询中,GROUP BY 可以起到同 ORDER BY 相同的作用。
返回多行数据的子查询只能同多值操作符一起使用,比如IN 操作符
SELECT 列表中不能包含任何对BLOB、ARRAY、CLOB 或者 NCLOB 类型值的引用。
子查询不能直接用在集合函数中。
BETWEEN 操作符不能同子查询一起使用,但是BETWEEN 操作符可以用在子查询中。
SELECT 语句中的子查询通常情况下子查询都与 SELECT 语句一起使用,其基本语法如下所示:

SELECT column_name [, column_name ]
FROM   table1 [, table2 ]
WHERE  column_name OPERATORSELECT column_name [, column_name ]FROM table1 [, table2 ][WHERE])
  • 示例:考虑CUSTOMERS 表,表中记录如下所示:
+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  35 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+
  • select子查询的语句如下:
SQL> SELECT * FROM CUSTOMERS WHERE ID IN SELECT ID FROM CUSTOMERS WHERE SALARY > 4500) ;

上述语句的执行结果如下所示:

+----+----------+-----+---------+----------+
| ID | NAME     | AGE | ADDRESS | SALARY   |
+----+----------+-----+---------+----------+
|  4 | Chaitali |  25 | Mumbai  |  6500.00 |
|  5 | Hardik   |  27 | Bhopal  |  8500.00 |
|  7 | Muffy    |  24 | Indore  | 10000.00 |
+----+----------+-----+---------+----------+
  • insert 语句中的子查询:子查询还可以用在 INSERT 语句中,INSERT语句可以将子查询返回的数据插入到其他表中。子查询中选取的数据可以被任何字符、日期或者数值函数所修饰。其基本语法如下所示:
INSERT INTO table_name [ column1 [, column2 ]) ]SELECT [ *|column1 [, column2 ]FROM table1 [, table2 ][ WHERE VALUE OPERATOR ]

示例:考虑与 CUSTOMERS 表拥有相似结构的 CUSTOMERS_BKP 表。现在要将CUSTOMER 表中所有的数据复制到 CUSTOMERS_BKP 表中,代码如下:

INSERT INTO CUSTOMERS_BKPSELECT * FROM CUSTOMERS WHERE ID IN SELECT ID FROM CUSTOMERS) ;
  • UPDATE 语句中的子查询:子查询可以用在 UPDATE 语句中。当子查询同 UPDATE 一起使用的时候,既可以更新单个列,也可更新多个列。其基本语法如下:
UPDATE table
SET column_name = new_value
[ WHERE OPERATOR [ VALUE ]SELECT COLUMN_NAMEFROM TABLE_NAME)[ WHERE) ]

示例:假设我们有一份 CUSTOMERS_BKP 表作为CUSTOMERS 表的备份。下面的示例将 CUSTOMERS 表中所有AGE大于或者等于 27 的客户的SALARY字段都变为了原来的 0.25 倍:

UPDATE CUSTOMERSSET SALARY = SALARY * 0.25WHERE AGE IN SELECT AGE FROM CUSTOMERS_BKPWHERE AGE >= 27 );

这将影响两行数据,随后CUSTOMERS 表中的记录将如下所示:

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  35 | Ahmedabad |   125.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  2125.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+
  • DELETE 语句中的子查询:如同前面提到的其他语句一样,子查询还可以同 DELETE 语句一起使用。其基本语法如下所示:
DELETE FROM TABLE_NAME
[ WHERE OPERATOR [ VALUE ]SELECT COLUMN_NAMEFROM TABLE_NAME)[ WHERE) ]

示例:假设我们有一份CUSTOMERS_BKP 表作为CUSTOMERS 表的备份。下面的示例将从CUSTOMERS 表中删除所有 AGE 大于或者等于 27 的记录:

DELETE FROM CUSTOMERSWHERE AGE IN SELECT AGE FROM CUSTOMERS_BKPWHERE AGE > 27 );

这将影响两行数据,随后CUSTOMERS 表中的记录将如下所示:

+----+----------+-----+---------+----------+
| ID | NAME     | AGE | ADDRESS | SALARY   |
+----+----------+-----+---------+----------+
|  2 | Khilan   |  25 | Delhi   |  1500.00 |
|  3 | kaushik  |  23 | Kota    |  2000.00 |
|  4 | Chaitali |  25 | Mumbai  |  6500.00 |
|  6 | Komal    |  22 | MP      |  4500.00 |
|  7 | Muffy    |  24 | Indore  | 10000.00 |
+----+----------+-----+---------+----------+

9、插入数据、更新和删除数据

  • INSERT INTO 语句(插入数据):INSERT INTO 语句用于向表格中插入新的行数据)。可以同时插入多行数据。
  • 语法:
INSERT INTO 表名称 VALUES 1,2,....);//--指定所要插入数据的列--
INSERT INTO 表名称 1,2,...) VALUES 1,2,....);

注意:1、尽量采用指定列名的方法进行插入数据,这样即使表的结构改变,此INSERT语句仍然能够正确工作。
2、如果数据检索是最重要的,可以通过在 INSERT 和 INTO 之间添加关键字 LOW_PRIORITY,指示数据库(MySQL)降低INSERT 语句的优先级。
3、不管使用哪一种INSERT语法,都必须给出 VALUES 的正确数目。

  • 插入检索的数据:可以利用INSERT INTO 语句将一条 SELECT 语句的结果插入表中,这就是 INSERT SELECT,即它是由一条INSERT 语句 和 一条SELECT 语句组成的。SELECT 语句可以与WHERE 等子句联合使用,这样可以过滤插入的数据。

  • 注意:INSERT SELECT 语句插入多少行取决于 SELECT 语句中的表有多少行,若这个表为空,则没有行被插入(也不会产生错误,因为操作仍然是合法的)。

  • 语法:

INSERT INTO 表名称列名1,列名2,列名3……) SELECT 列名1,列名2,列名3…… FROM 表名
  • DELETE 语句(删除数据行),DELETE 语句用于删除表中的行。
  • 语法:
DELETE FROM 表名称 WHERE 列名称 =;

删除所有行:可以在不删除表的情况下删除所有的行,这意味着表的结构、属性和索引都是完整的。

  • 语法:
DELETE FROM 表名称;DELETE * FROM 表名称;TRUNCATE TABLE;

注意:如果想从表中删除所有行,尽量使用 TRUNCATE TABLE语句,它完成相同的工作,但是速度更快,因为 TRUNCATE TABLE语句实际是删除原来的表病重新创建一个表,而不是逐行删除表中的数据。

  • Update 语句(修改数据),Update 语句用于修改表中的数据。可以同时修改多个值。

注意:在使用 UPDATE 语句时一定不要省略 WHERE 子句。

  • 语法:
UPDATE 表名称 SET 列名称1 = 新值1, 列名称2 = 新值2 WHERE 列名称 = 某值;
IGNORE关键字:即使发生错误也继续更新。UPDATE IGNORE 表名称 ……

10、多表查询

内连接:合并具有同一列的两个以上的表的行,结果集中不包含一个表与另一个表不匹配的行;

1、多表查询会产生笛卡尔积:

假设集合a={b,c},集合b={0,1,2},则两个集合的笛卡尔积为{(b,0),(b,1),(b,2),(c,0),(c,1),(c,2)}

实际运行环境线下,应避免使用权笛卡尔积;

解决方案:在where加入有效的条件———->等值连接(等值连接找的是列的值一样的数据,跟列名称和列类型无关)

2、内连接查询使用的关键字inner join)

  • 隐式内连接: select * from A,B where 条件;
  • 显示内连接: select * from A inner join B on 条件;

后面接两张表中需要关联的字段 字段名称不需要一样 A.id = B.id )

外连接:两个表在连接过程中除了返回满足连接条件的行以外还返回左(或右)表中不满足条件的行 ,这种连接称为左(或右) 外连接。没有匹配的行时, 结果表中相应的列为空NULL);外连接的 WHERE 子句条件类似于内部连接,但连接条件中没有匹配行的表的列后面要加外连接运算符,即用圆括号括起来的加号+);

左外连接LEFT JOIN的含义就是求两个表的交集外加左表剩下的数据。依旧从笛卡尔积的角度讲,就是先从笛卡尔积中挑出ON子句条件成立的记录,然后加上左表中剩余的记录;

select a.*,b.* from a left [outer] join b on 连接条件;  注意:outer 可以不写
意思:先展示join左边的a)表的所有数据,根据条件关联查询 join右边的表b),符合条件则展示出来,不符合以null值展示.

右外连接RIGHT JOIN就是求两个表的交集外加右表剩下的数据。再次从笛卡尔积的角度描述,右连接就是从笛卡尔积中挑出ON子句条件成立的记录,然后加上右表中剩余的记录;

select a.*,b.* from b right [outer] join a on 连接条件;  注意:outer 可以不写
意思:先展示jion右边的表a)表的所有数据,根据条件关联查询join左边的表b),符合条件则展示出来,不符合以null值展示.

练习:

1、查询用户的订单,没有订单的用户不显示

隐式内连接:
select user.*,orders.* from user ,orders where user.id=orders.user_id;
显示内连接:
select user.*,orders.* from user join orders on user.id=orders.user_id;

2、查询所有用户的订单详情

左外连接: user在左
select user.*,orders.* from user left join orders on user.id=orders.user_id;

3、查询所有订单的用户详情

右外连接:orders 在右
select orders.*,user.* from user right join orders on user.id=orders.user_id;

4、查看用户为张三的订单详情

先查询张三的id:
select id from User where username = '张三';// 3
再从订单表中查询用户id与张三id一样的订单信息:
select * from orders where user_id = ?;
两个合二为一,注意:后面的条件 把括号带上
select * from orders where user_id = select id from User where username = '张三'); --注意带上括号

5、查询出订单的价格大于300的所有用户信息。

1.先查询出订单价格>300的用户的id:
select user_id from orders where price >300;//3,3,5,null)
2.再查询符合条件的用户的所有信息:
select * from user where id in3,3,5,null);
3.两个合二为一:
select * from user where id inselect user_id from orders where price >300);

6、查询订单价格大于300的订单信息及相关用户的信息。

方式1:内连接:
select orders.*,user.* from orders,user where user.id=orders.user_id  and orders.price>300 ;
方式2:子查询,是将一个查询的结果作为一张临时表,先查出订单大于三百的订单,然后把可以作为一个临时表
select * from orders where price>300
合二为一条,注意给临时表起个别名,注意给表起别名,名字不要带引号,其实用的就是内连接 查两张表,注意把临时表用户括号括起来
select user.*,tmp.* from user,select * from orders where price>300) as tmp where user.id=tmp.user_id;
  • 给表起别名:
格式: 表 [as] 别名

7、自连接查询—通过表的别名,给一张表起两个别名,将它视为两张表来进行查询;

比如:我要查询emp表中员工姓名所对应的老板姓名,因为这些信息都在一张表emp中,比如 员工号7369 的 SMITH,他对应的老板编号是MGR) 7902 ,而7902 又是员工FORD7902) 那FORD 对应的老板编号又是7566,所以说,一个员工既是某几个员工的老板,他也有自己的老板,所以我要查询这个员工的所对应的老板,就可以使用自连接查询,我们假设有两张表一张员工表、一张老板表,如果员工的老板号=老板的员工号,就表示这个员工是另外一个员工的老板:

select e.ename as 员工姓名,b.ename as 老板姓名 from emp e,emp b where e.mgr=b.empno; 

Published by

风君子

独自遨游何稽首 揭天掀地慰生平

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注