掌握 SQL 这些核心知识点,出去吹牛逼再也不担心了

第一章 SQL的介绍

1.1、什么是sql

1.2、sql的分类

1.3、MySQL的语法规范和要求

(1)mysql的sql语法不区分大小写

MySQL的关键字和函数名等不区分大小写,但是对于数据值是否区分大小写,和字符集与校对规则有关。

ci(大小写不敏感),cs(大小写敏感),_bin(二元,即比较是基于字符编码的值而与language无关,区分大小写)

(2)命名时:尽量使用26个英文字母大小写,数字0-9,下划线,不要使用其他符号user_id

(3)建议不要使用mysql的关键字等来作为表名、字段名等,如果不小心使用,请在SQL语句中使用`(飘号)引起来

(4)数据库和表名、字段名等对象名中间不要包含空格

(5)同一个mysql软件中,数据库不能同名,同一个库中,表不能重名,同一个表中,字段不能重名

(6)标点符号:

(7)SQL脚本中如何加注释

#以下两句是一样的,不区分大小写
show databases;
SHOW DATABASES;

#创建表格
#create table student info(...); #表名错误,因为表名有空格
create table student_info(...); 

#其中name使用``飘号,因为name和系统关键字或系统函数名等预定义标识符重名了。
CREATE TABLE t_stu(
    id INT,
    `name` VARCHAR(20)
);

select id as "编号", `name` as "姓名" from t_stu; #起别名时,as都可以省略
select id as 编号, `name` as 姓名 from t_stu; #如果字段别名中没有空格,那么可以省略""
select id as 编 号, `name` as 姓 名 from t_stu; #错误,如果字段别名中有空格,那么不能省略""

第二章-DDL操作数据库

2.1、创建数据库(掌握)

create database 数据库名 [character set 字符集][collate  校对规则]     注: []意思是可选的意思

字符集(charset):是一套符号和编码。

创建一个day01的数据库(默认字符集)

create database day01;

创建一个day01_2的数据库,指定字符集为gbk(了解)

create database day01_2 character set gbk;

2.2、查看所有的数据库

语法

show databases; 

语法

show create database 数据库名;

查看day01这个数据库的定义

show create database day01; 

2.3、删除数据库

语法

drop database 数据库名;

删除day01_2数据库

drop database day01_2;

2.4、修改数据库【了解】

语法

alter database 数据库名 character set 字符集;

修改day01这个数据库的字符集(gbk)

alter database day01 character set gbk;

注意:

2.5、其他操作

切换数据库, 选定哪一个数据库

use 数据库名;           //注意: 在创建表之前一定要指定数据库. use 数据库名

练习: 使用day01

use day01;

查看正在使用的数据库

select database();

第三章-DDL操作表

3.1、创建表

数值类型

整型系列:xxxInt

掌握 SQL 这些核心知识点,出去吹牛逼再也不担心了

浮点型系列:float,double(或real)

位类型:bit

用来存储二进制数。对于位字段,直接使用select命令将不会看到结果。可以使用bit()或hex()函数进行读取。插入bit类型字段时,使用bit()函数转为二进制值再插入,因为二进制码是“01”。

日期时间类型

日期时间类型:year, date, datetime, timestamp

注意一下每一种日期时间的表示范围

掌握 SQL 这些核心知识点,出去吹牛逼再也不担心了

timestamp和datetime的区别:

掌握 SQL 这些核心知识点,出去吹牛逼再也不担心了

掌握 SQL 这些核心知识点,出去吹牛逼再也不担心了

字符串类型

MySQL中提供了多种对字符数据的存储类型,不同的版本可能有所差异。常见的有:

char,varchar,xxtext,binary,varbinary,xxblob,enum,set等等
掌握 SQL 这些核心知识点,出去吹牛逼再也不担心了

binary和varbinary类似于char和varchar,不同的是它们包含二进制字符串,不支持模糊查询之类的。

一般在保存少量字符串的时候,我们会选择char和varchar;而在保存较大文本时,通常会选择使用text或blob系列。blob和text值会引起一些性能问题,特别是在执行了大量的删除操作时,会在数据表中留下很大的“空洞”,为了提高性能,建议定期时候用optimize table功能对这类表进行碎片整理。可以使用合成的(Synthetic)索引来提高大文本字段的查询性能,如果需要对大文本字段进行模糊查询,MySql提供了前缀索引。但是仍然要在不必要的时候避免检索大型的blob或text值。

enum枚举类型,它的值范围需要在创建表时通过枚举方式显式指定,对于1~255个成员的枚举需要1个字节存储;对于【 255`65535】个成员需要2个字节存储。例如:gender enum(‘男’,‘女’)。如果插入枚举值以外的值,会按第一个值处理。一次只能从枚举值中选择一个。

set集合类型,可以包含0~64个成员。一次可以从集合中选择多个成员。如果选择了1-8个成员的集合,占1个字节,依次占2个,3个。。8个字节。例如:hoppy set(‘吃饭’,‘睡觉’,‘玩游戏’,‘旅游’),选择时’吃饭,睡觉’或’睡觉,玩游戏,旅游’

示例

+----------------+--------------+------+-----+---------+----------------+
| Field          | Type         | Null | Key | Default | Extra          |
+----------------+--------------+------+-----+---------+----------------+
| eid            | int(11)      | NO   | PRI | NULL    | auto_increment |
| ename          | varchar(20)  | NO   |     | NULL    |                |
| tel            | char(11)     | NO   |     | NULL    |                |
| gender         | char(1)      | YES  |     | 男        |                |
| salary         | double       | YES  |     | NULL    |                |
| commission_pct | double(3,2)  | YES  |     | NULL    |                |
| birthday       | date         | YES  |     | NULL    |                |
| hiredate       | date         | YES  |     | NULL    |                |
| job_id         | int(11)      | YES  |     | NULL    |                |
| email          | varchar(32)  | YES  |     | NULL    |                |
| mid            | int(11)      | YES  |     | NULL    |                |
| address        | varchar(150) | YES  |     | NULL    |                |
| native_place   | varchar(10)  | YES  |     | NULL    |                |
| did            | int(11)      | YES  |     | NULL    |                |
+----------------+--------------+------+-----+---------+----------------+

约束

掌握 SQL 这些核心知识点,出去吹牛逼再也不担心了

约束种类:

注意:

id列:

练习

创建一张学生表(含有id字段,姓名字段不能重复,性别字段不能为空默认值为男. id为主键自动增长)

CREATE TABLE student(
    id INT PRIMARY KEY AUTO_INCREMENT, -- 主键自增长
    NAME VARCHAR(30) UNIQUE, -- 唯一约束
    gender CHAR(1) NOT NULL DEFAULT '男'
);

3.2、查看表【了解】

查看所有的表

show tables;

查看表的定义结构

语法

desc 表名;

练习: 查看student表的定义结构

desc student;

3.3、修改表【掌握,但是不要记忆】

语法

alter table 【数据库名.]表名称 add 【column】 字段名 数据类型;
alter table 【数据库名.]表名称 add 【column】 字段名 数据类型 first;
alter table 【数据库名.]表名称 add 【column】 字段名 数据类型 after 另一个字段;

练习

给学生表增加一个grade字段,类型为varchar(20),不能为空

ALTER TABLE student ADD grade VARCHAR(20) NOT NULL;

给学生表的gender字段改成int类型,不能为空,默认值为1

alter table student modify gender varchar(20);

给学生表的grade字段修改成class字段

ALTER TABLE student CHANGE grade class VARCHAR(20) NOT NULL;

把class字段删除

ALTER TABLE student DROP class;

把学生表修改成老师表(了解)

RENAME TABLE student TO teacher;

3.4、删除表【掌握】

语法

drop table 表名;

把teacher表删除

drop table teacher;

第四章-DML操作表记录-增删改【重点】

准备工作: 创建一张商品表(商品id,商品名称,商品价格,商品数量.)

create table product(
    pid int primary key auto_increment,
    pname varchar(40),
    price double,
    num int
);

4.1、插入记录

语法

eg: 只想插入pname, price , insert into t_product(pname, price) values(‘mac’,18000);

insert into 表名(列,列..) values(值,值..);

注意: 如果没有插入了列设置了非空约束, 会报错的

insert into 表名 values(值,值....);

eg:

insert into product values(null,'苹果电脑',18000.0,10);
insert into product values(null,'华为5G手机',30000,20);
insert into product values(null,'小米手机',1800,30);
insert into product values(null,'iPhonex',8000,10);
insert into product values(null,'iPhone7',6000,200);
insert into product values(null,'iPhone6s',4000,1000);
insert into product values(null,'iPhone6',3500,100);
insert into product values(null,'iPhone5s',3000,100);

insert into product values(null,'方便面',4.5,1000);
insert into product values(null,'咖啡',11,200); 
insert into product values(null,'矿泉水',3,500);

4.2、更新记录

update 表名 set 列 =值, 列 =值 [where 条件]

将所有商品的价格修改为5000元

update product set price = 5000;

将商品名是苹果电脑的价格修改为18000元

UPDATE product set price = 18000 WHERE pname = '苹果电脑';

将商品名是苹果电脑的价格修改为17000,数量修改为5

UPDATE product set price = 17000,num = 5 WHERE pname = '苹果电脑';

将商品名是方便面的商品的价格在原有基础上增加2元

UPDATE product set price = price+2 WHERE pname = '方便面';

4.3、删除记录

根据条件,一条一条数据进行删除

语法

delete from 表名 [where 条件]    注意: 删除数据用delete,不用truncate

类型

删除表中名称为’苹果电脑’的记录

delete from product where pname = '苹果电脑';

删除价格小于5001的商品记录

delete from product where price < 5001;

删除表中的所有记录(要删除一般不建议使用delete语句,delete语句是一行一行执行,速度过慢)

delete from product;

第五章-DQL操作表记录-查询【重点】

5.1、基本查询语法

select 要查询的字段名 from 表名 [where 条件] 

5.2、简单查询

查询所有行和所有列的记录

查询某张表特定列的记录

别名查询

把商品名,和商品价格+10查询出来:我们既可以将某个字段加上一个固定值,又可以对多个字段进行运算查询

select pname ,price+10 as 'price' from product;
select name,chinese+math+english as total from student

注意

5.3、条件查询(很重要)

1、比较运算符

大于:>
小于:<
大于等于:>=
小于等于:<=
等于:=   不能用于null判断
不等于:!=  或 <>
安全等于: <=>  可以用于null值判断

2、逻辑运算符(建议用单词,可读性来说)

逻辑与:&& 或 and
逻辑或:|| 或 or
逻辑非:! 或 not
逻辑异或:^ 或 xor

3、范围

区间范围:between x  and  y
        not between x  and  y
集合范围:in (x,x,x) 
        not  in (x,x,x)

4、模糊查询和正则匹配(只针对字符串类型,日期类型)

like 'xxx'  模糊查询是处理字符串的时候进行部分匹配
如果想要表示0~n个字符,用%
如果想要表示确定的1个字符,用_

regexp '正则'

5、特殊的null值处理

#(1)判断时
xx is null
xx is not null
xx <=> null
#(2)计算时
ifnull(xx,代替值) 当xx是null时,用代替值计算

查询商品价格>3000的商品

select * from product where price > 3000;

查询pid=1的商品

select * from product where pid = 1;

查询pid<>1的商品(!=)

select * from product where pid <> 1;

查询价格在3000到6000之间的商品

select * from product where price between 3000 and 6000;

查询pid在1,5,7,15范围内的商品

select * from product where id = 1;
select * from product where id = 5;
select * from product where id = 7;
select * from product where id = 15;

select * from product where id in (1,5,7,15);

查询商品名以iPho开头的商品(iPhone系列)

select * from product where pname like 'iPho%';

查询商品价格大于3000并且数量大于20的商品 (条件 and 条件 and…)

select * from product where price > 3000 and num > 20;

查询id=1或者价格小于3000的商品

select * from product where pid = 1 or price < 3000;

5.4、排序查询

排序是写在查询的后面,代表把数据查询出来之后再排序

语法: 只按某一个字段进行排序,单列排序

SELECT 字段名 FROM 表名 [WHERE 条件] ORDER BY 字段名 [ASC|DESC];  //ASC: 升序,默认值; DESC: 降序

案例: 以分数降序查询所有的学生

SELECT * FROM student ORDER BY score DESC

语法: 同时对多个字段进行排序,如果第1个字段相等,则按第2个字段排序,依次类推

SELECT 字段名 FROM 表名 WHERE 字段=值 ORDER BY 字段名1 [ASC|DESC], 字段名2 [ASC|DESC];

练习: 以分数降序查询所有的学生, 如果分数一致,再以age降序

SELECT * FROM student ORDER BY score DESC, age DESC

5.5、聚合函数

聚合函数用于统计,通常会和分组查询一起使用,用于统计每组的数据

掌握 SQL 这些核心知识点,出去吹牛逼再也不担心了

语法

SELECT 聚合函数(列名) FROM 表名 [where 条件];

案例

-- 求出学生表里面的最高分数
SELECT MAX(score) FROM student
-- 求出学生表里面的最低分数
SELECT MIN(score) FROM student
-- 求出学生表里面的分数的总和(忽略null值)
SELECT SUM(score) FROM student
-- 求出学生表里面的平均分
SELECT AVG(score) FROM student
-- 求出学生表里面的平均分(缺考了当成0分处理)
SELECT AVG(IFNULL(score,0)) FROM student
-- 统计学生的总人数 (忽略null) 
SELECT COUNT(sid) FROM student
SELECT COUNT(*) FROM student

注意: 聚合函数会忽略空值NULL

我们发现对于NULL的记录不会统计,建议如果统计个数则不要使用有可能为null的列,但如果需要把NULL也统计进去呢?我们可以通过 IFNULL(列名,默认值) 函数来解决这个问题. 如果列不为空,返回这列的值。如果为NULL,则返回默认值。

-- 求出学生表里面的平均分(缺考了当成0分处理)
SELECT AVG(IFNULL(score,0)) FROM student;

5.6、分组查询

GROUP BY将分组字段结果中相同内容作为一组,并且返回每组的第一条数据,所以单独分组没什么用处。分组的目的就是为了统计,一般分组会跟聚合函数一起使用

语法

SELECT 字段1,字段2... FROM 表名  [where 条件] GROUP BY 列 [HAVING 条件];

案例

-- 根据性别分组, 统计每一组学生的总人数
SELECT sex '性别',COUNT(sid) '总人数' FROM student GROUP BY sex

-- 根据性别分组,统计每组学生的平均分
SELECT sex '性别',AVG(score) '平均分' FROM student GROUP BY sex

-- 根据性别分组,统计每组学生的总分
SELECT sex '性别',SUM(score) '总分' FROM student GROUP BY sex

分组后的条件,不能写在where之后,where关键字要写在group by之前

根据性别分组, 统计每一组学生的总人数> 5的(分组后筛选)

SELECT sex, count(*) FROM student GROUP BY sex HAVING count(sid) > 5

根据性别分组,只统计年龄大于等于18的,并且要求组里的人数大于4

SELECT sex '性别',COUNT(sid) '总人数' FROM student WHERE age >= 18 GROUP BY sex HAVING COUNT(sid) > 4

where 子句作用

having字句作用

5.7、分页查询

掌握 SQL 这些核心知识点,出去吹牛逼再也不担心了

好的数据库设计对数据的存储性能和后期的程序开发,都会产生重要的影响。建立科学的,规范的数据库就需要满足一些规则来优化数据的设计和存储,这些规则就称为范式。

6.1、第一范式: 确保每列保持原子性

第一范式是最基本的范式。如果数据库表中的所有字段值都是不可分解的原子值,就说明该数据库表满足了第一范式。

第一范式的合理遵循需要根据系统的实际需求来定。比如某些数据库系统中需要用到“地址”这个属性,本来直接将“地址”属性设计成一个数据库表的字段就行。但是如果系统经常会访问“地址”属性中的“城市”部分,那么就非要将“地址”这个属性重新拆分为省份、城市、详细地址等多个部分进行存储,这样在对地址中某一部分操作的时候将非常方便。这样设计才算满足了数据库的第一范式,如下表所示。

掌握 SQL 这些核心知识点,出去吹牛逼再也不担心了

如果不遵守第一范式,查询出数据还需要进一步处理(查询不方便)。遵守第一范式,需要什么字段的数据就查询什么数据(方便查询)

6.2、第二范式: 确保表中的每列都和主键相关

第二范式在第一范式的基础之上更进一层。第二范式需要确保数据库表中的每一列都和主键相关,而不能只与主键的某一部分相关(主要针对联合主键而言)。也就是说在一个数据库表中,一个表中只能保存一种数据,不可以把多种数据保存在同一张数据库表中。

比如要设计一个订单信息表,因为订单中可能会有多种商品,所以要将订单编号和商品编号作为数据库表的联合主键,如下表所示

掌握 SQL 这些核心知识点,出去吹牛逼再也不担心了

这样就产生一个问题:这个表中是以订单编号和商品编号作为联合主键。这样在该表中商品名称、单位、商品价格等信息不与该表的主键相关,而仅仅是与商品编号相关。所以在这里违反了第二范式的设计原则。

而如果把这个订单信息表进行拆分,把商品信息分离到另一个表中,把订单项目表也分离到另一个表中,就非常完美了。如下所示

这样设计,在很大程度上减小了数据库的冗余。如果要获取订单的商品信息,使用商品编号到商品信息表中查询即可

6.3、第三范式: 确保每列都和主键列直接相关,而不是间接相关

第三范式需要确保数据表中的每一列数据都和主键直接相关,而不能间接相关。

比如在设计一个订单数据表的时候,可以将客户编号作为一个外键和订单表建立相应的关系。而不可以在订单表中添加关于客户其它信息(比如姓名、所属公司等)的字段。如下面这两个表所示的设计就是一个满足第三范式的数据库表。

这样在查询订单信息的时候,就可以使用客户编号来引用客户信息表中的记录,也不必在订单信息表中多次输入客户信息的内容,减小了数据冗余

第七章 外键约束

7.1、外键约束的概念

在遵循三范式的前提下,很多时候我们必须要进行拆表,将数据分别存放在多张表中,以减少冗余数据。但是拆分出来的表与表之间是有着关联关系的,我们必须得通过一种约束来约定表与表之间的关系,这种约束就是外键约束

7.2、外键约束的作用

外键约束是保证一个或两个表之间的参照完整性,外键是构建于一个表的两个字段或是两个表的两个字段之间的参照关系。

7.3、创建外键约束的语法

7.6、外键约束等级

7.7、外键约束练习

-- 部门表
create table dept( 
    id int primary key,
    dept_name varchar(50),
    dept_location varchar(50)
);
-- 员工表
CREATE TABLE emp(
    eid int primary key,
    name varchar(50) not null,
    sex varchar(10),
    dept_id int
);
-- 给员工表表的dept_id添加外键指向部门表的主键
alter table emp add foreign key(dept_id) references dept(id)

第八章 多表间关系

8.1、一对多关系

一对多的关系是指: 主表的一行数据可以同时对应从表的多行数据,反过来就是从表的多行数据指向主表的同一行数据。

分类表和商品表、班级表和学生表、用户表和订单表等等

将一的一方作为主表,多的一方作为从表,在从表中指定一个字段作为外键,指向主表的主键

掌握 SQL 这些核心知识点,出去吹牛逼再也不担心了

两张表都是多的一方,A表的一行数据可以同时对应B表的多行数据,反之B表的一行数据也可以同时对应A表的多行数据

订单表和商品表、学生表和课程表等等

因为两张表都是多的一方,所以在两张表中都无法创建外键,所以需要新创建一张中间表,在中间表中定义两个字段,这俩字段分别作为外键指向两张表各自的主键

掌握 SQL 这些核心知识点,出去吹牛逼再也不担心了

我们之前学习过一对多关系,在一对多关系中主表的一行数据可以对应从表的多行数据,反之从表的一行数据则只能对应主表的一行数据。这种一行数据对应一行数据的关系,我们可以将其看作一对一关系

A表中的一行数据对应B表中的一行数据,反之B表中的一行数据也对应A表中的一行数据,此时我们可以将A表当做主表B表当做从表,或者是将B表当做主表A表当做从表

在从表中指定一个字段创建外键并指向主表的主键,然后给从表的外键字段添加唯一约束

第九章 多表关联查询

多表关联查询是使用一条SQL语句,将关联的多张表的数据查询出来

9.1、环境准备

-- 创建一张分类表(类别id,类别名称.备注:类别id为主键并且自动增长)
CREATE TABLE t_category(
        cid INT PRIMARY KEY auto_increment,
        cname VARCHAR(40)
);
INSERT INTO t_category values(null,'手机数码');
INSERT INTO t_category values(null,'食物');
INSERT INTO t_category values(null,'鞋靴箱包');


-- 创建一张商品表(商品id,商品名称,商品价格,商品数量,类别.备注:商品id为主键并且自动增长)

CREATE TABLE t_product(
        pid INT PRIMARY KEY auto_increment,
        pname VARCHAR(40),
        price DOUBLE,
        num INT,
        cno INT
);

insert into t_product values(null,'苹果电脑',18000,10,1);
insert into t_product values(null,'iPhone8s',5500,100,1);
insert into t_product values(null,'iPhone7',5000,100,1);
insert into t_product values(null,'iPhone6s',4500,1000,1);
insert into t_product values(null,'iPhone6',3800,200,1);
insert into t_product values(null,'iPhone5s',2000,10,1);
insert into t_product values(null,'iPhone4s',18000,1,1);

insert into t_product values(null,'方便面',4.5,1000,2);
insert into t_product values(null,'咖啡',10,100,2);
insert into t_product values(null,'矿泉水',2.5,100,2);

insert into t_product values(null,'法拉利',3000000,50,null);

-- 给 商品表添加外键
ALTER TABLE t_product ADD FOREIGN KEY(cno) REFERENCES t_category(cid);

9.2、交叉查询【了解】

交叉查询其实就是将多张表的数据没有条件地连接在一起进行展示

使用交叉查询类别和商品

select * from t_category,t_product;

通过查询结果我们可以看到,交叉查询其实是一种错误的做法,在查询到的结果集中有大量的错误数据,我们称交叉查询到的结果集是笛卡尔积

假设集合A={a,b},集合B={0,1,2},则两个集合的笛卡尔积为{(a,0),(a,1),(a,2),(b,0),(b,1),(b,2)}。可以扩展到多个集合的情况。

9.3、内连接查询

交叉查询产生这样的结果并不是我们想要的,那么怎么去除错误的、不想要的记录呢,当然是通过条件过滤。通常要查询的多个表之间都存在关联关系,那么就通过关联关系(主外键关系)去除笛卡尔积。这种通过条件过滤去除笛卡尔积的查询,我们称之为连接查询。连接查询又可以分为内连接查询和外连接查询,我们先学习内连接查询

隐式内连接查询里面是没有inner join关键字

select [字段,字段,字段] from a,b where 连接条件 (b表里面的外键 = a表里面的主键 ) 

显式内连接查询里面是有inner join关键字

select [字段,字段,字段] from a [inner] join b on 连接条件 [ where 其它条件]

查询所有类别下的商品信息,如果该类别下没有商品则不展示

-- 1 隐式内连接方式 
select *from t_category  c, t_product  p WHERE c.cid = p.cno;

-- 2 显示内连接方式
-- 查询手机数码这个分类下的所有商品的信息以及分类信息
SELECT * FROM t_product tp INNER JOIN t_category tc ON tp.cno = tc.cid WHERE tc.cname = '手机数码';

SELECT * from t_category c INNER JOIN t_product p ON c.cid = p.cno

主表和从表中的数据都是满足连接条件则能够查询出来,不满足连接条件则不会查询出来

9.4、外连接查询

我们发现内连接查询出来的是满足连接条件的公共部分, 如果要保证查询出某张表的全部数据情况下进行连接查询. 那么就要使用外连接查询了. 外连接分为左外连接和右外连接

概念

以join左边的表为主表,展示主表的所有数据,根据条件查询连接右边表的数据,若满足条件则展示,若不满足则以null显示。可以理解为:在内连接的基础上保证左边表的数据全部显示

语法

select 字段 from a left [outer] join b on 条件

练习

查询所有类别下的商品信息,就算该类别下没有商品也需要将该类别的信息展示出来

SELECT * FROM t_category c LEFT OUTER JOIN t_product p ON c.cid = p.cno

概念

以join右边的表为主表,展示右边表的所有数据,根据条件查询join左边表的数据,若满足则展示,若不满足则以null显示。可以理解为:在内连接的基础上保证右边表的数据全部显示

语法

select 字段 from a right [outer] join b on 条件

练习

查询所有商品所对应的类别信息

SELECT * FROM t_category c RIGHT  OUTER JOIN t_product p ON c.cid = p.cno

9.5、union联合查询实现全外连接查询

首先要明确,联合查询不是多表连接查询的一种方式。联合查询是将多条查询语句的查询结果合并成一个结果并去掉重复数据。

全外连接查询的意思就是将左表和右表的数据都查询出来,然后按照连接条件连接

自连接查询是一种特殊的多表连接查询,因为两个关联查询的表是同一张表,通过取别名的方式来虚拟成两张表,然后进行两张表的连接查询

查询员工的编号,姓名,薪资和他领导的编号,姓名,薪资

#这些数据全部在员工表中
#把t_employee表,即当做员工表,又当做领导表
#领导表是虚拟的概念,我们可以通过取别名的方式虚拟
SELECT employee.id "员工的编号",emp.ename "员工的姓名" ,emp.salary "员工的薪资",
    manager.id "领导的编号" ,manager.ename "领导的姓名",manager.salary "领导的薪资"
FROM emp employee INNER JOIN emp manager
#emp employee:employee.,表示的是员工表的
#emp manager:如果用manager.,表示的是领导表的
ON employee.mgr = manager.id  # 员工的mgr指向上级的id

#表的别名不要加"",给列取别名,可以用"",列的别名不使用""也可以,但是要避免包含空格等特殊符号。

第十章 子查询

如果一个查询语句嵌套在另一个查询语句里面,那么这个查询语句就称之为子查询,根据位置不同,分为:where型,from型,exists型。注意:不管子查询在哪里,子查询必须使用()括起来。

10.1、where型

①子查询是单值结果(单行单列),那么可以对其使用(=,>等比较运算符)

# 查询价格最高的商品信息
select * from t_product where price = (select max(price) from t_product)

②子查询是多值结果,那么可对其使用(【not】in(子查询结果),或 >all(子查询结果),或>=all(子查询结果),any(子查询结果),或>=any(子查询结果),

# 查询价格最高的商品信息
SELECT * FROM t_product WHERE price >=ALL(SELECT price FROM t_product)
select * from t_product order by price desc limit 0,1

10.2、from型

子查询的结果是多行多列的结果,类似于一张表格。

必须给子查询取别名,即临时表名,表的别名不要加“”和空格。

-- 思路一: 使用连接查询
-- 使用外连接,查询出分类表的所有数据
SELECT tc.cname,COUNT(tp.pid) FROM t_category tc LEFT JOIN t_product tp ON tp.cno = tc.cid GROUP BY tc.cname

-- 思路二: 使用子查询
-- 第一步:对t_product根据cno进行分组查询,统计每个分类的商品数量
SELECT cno,COUNT(pid) FROM t_product GROUP BY cno
-- 第二步: 用t_category表去连接第一步查询出来的结果,进行连接查询,此时要求查询出所有的分类
SELECT tc.cname,IFNULL(tn.total,0) '总数量' FROM t_category tc LEFT JOIN (SELECT cno,COUNT(pid) total FROM t_product GROUP BY cno) tn ON tn.cno=tc.cid

10.3、exists型

# 查询那些有商品的分类
SELECT cid,cname FROM t_category tc WHERE EXISTS (SELECT * FROM t_product tp WHERE tp.cno = tc.cid);

链接:blog.csdn.net/qq_42076902/article/details/121701974

展开阅读全文

页面更新:2024-04-24

标签:范式   知识点   别名   字段   语法   核心   条件   类型   关系   数据库   商品   数据

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2008-2024 All Rights Reserved. Powered By bs178.com 闽ICP备11008920号-3
闽公网安备35020302034844号

Top