MySQL基础入门学习【8】子查询与连接

1. 数据准备:

incorrect string value 错误时:

建表前写 SET NAMES utf8;

建表后写 ALTER TABLES tdb_goods CHARACTER SET utf8;

录入数据前重启MySQL一次

SELECT显示数据时如果是乱码: SET NAMES gbk;  在客户端以gbk的编码显示数据,只影响客户端显示,并不影响真实的数据表中的数据

2. 子查询(SubQuery):是指出现在其他SQL语句内的SELECT子句

e.g.  SELECT * FROM t1 WHERE col1= (SELECT col2 FROM t2);

其中 SELECT * FROM t1: 称为 Outer Query / Outer Statement;

  SELECT col2 FROM t2: 称为 SubQuery。

!!!注意: 

    子查询指嵌套在查询内部,且必须始终出现在圆括号内;

    子查询可以包含多个关键字或条件,如 DISTINCT, GROUP BY, ORDER BY, LIMIT,函数等;

    子查询的外层查询(外层查询:我们所知道的所有SQL(结构化查询语言)命令的统称)可以是 SELECT, INSERT, UPDATE, DELETE, SET 或 DO。

子查询可以返回标量、一行、一列或子查询。

子查询的结果可以在其他的SQL语句,如INSERT, UPDATE 以及SELECT等语句中使用。

(1) 使用比较运算符(= < > <= >= <> != <=>)的子查询:

  语法结构: operand comparison_operator (subquery)

e.g.查找商品的平均价格:

对数字做四舍五入,并保留到小数点后两位:

看看哪些商品的价格大于等于5636.36

 

查找超级本类型的商品的价格:

子查询返回多个结果时: 用ANY, SOME 或 ALL 修饰的比较运算符:(ANY, SOME等价,符合其中一个就行;ALL 符合全部)

operand comparison_operator ANY (subquery)   

operand comparison_operator SOME (subquery)

operand comparison_operator ALL (subquery)

原则:

  ANY SOME ALL
>, >= 最小值 最小值 最大值
<, <= 最大值 最大值 最小值
= 任意值 任意值  
<>, !=     任意值

 

e.g.查询哪些商品的价格大于超级本的价格:

 

 

 

 

 

(2)由[NOT] IN/EXISTS引发的子查询:

  (a) IN 或 NOT IN,语法结构: operand comparison_operator [NOT] IN (subquery)

  = ANY 运算符与IN等效

  != ALL 或<> ALL运算符与NOT IN 等效

 

(b) EXISTS 或 NOT EXISTS: 如果子查询返回任何行,EXISTS 将返回TRUE, 否则为FALSE。

 

(3) INSERT... SET... 与INSERT... VALUES...的区别在于 INSERT ... SET...可以使用子查询:

e.g. SET a字段=(Subquery)

 

  INSERT ... SELECT: 将查询结果写入数据表:

   INSERT [INTO] tbl_name [ (col_name,...) ] SELECT...

参照分类表(tdb_goods_cates) 更新商品表(tdb_goods),这就需要多表的更新:

3. 多表更新(参照另外的表来更新本表内的记录): 

方法一: 建立一个新的表,INSERT... SELECT 插入记录,UPDATE... join 

           UPDATE table_references

       SET col_name1= {expr | DEFAULT}

       [ , col_name2={expr|DEFAULT]...

       [WHERE where_condition]

 

 

方法二: 多表更新的一步到位: CREATE... SELECT ,即将方法一种创建数据表和查询写入记录的步骤两者合为一个命令,更为便捷。

    创建数据表的同时将查询结果写入到数据表:

    CREATE TABLE [IF NOT EXISTS] tbl_name 

    [ (create_definition,...)]

    select_statement

参照品牌表更新商品表:

注意,即使我们UPDATE之后,tdb_goods表中goods_cate 和 brand_name的类型仍然是VARCHAR(40)

 

尽量去修改表的结构

既要改字段的名字又要改数据类型  --> 利用CHANGE

至此,我们才给数据表做了减肥的操作。(即使后续有重复的,数字所占的字节数要远小于字符所占的字节数)

在创建外键时不一定非要加FOREIGN KEY(物理外键);我们也可以使用上述形式的外键(事实的外键),且这种形式较为常用。

 

 

由于没有物理外键,上图中即使tdb_goods_cates中没有cate_id=12,我们仍然可以在tdb_goods中插入一条cate_id为12的记录

 

当我们想要把记录的详细信息展示给客户看时,应该显示明确的商品的品牌、商品的分类,此时就需要这几张表的协作,这就需要连接来实现,操作解释如下:

4.  连接 (join)

MySQL在SELECT语句、多表更新、多表删除语句中都支持JOIN操作

(1) 连接的语法结构:

table_reference  (a表)

{ [INNER | CROSS] JOIN | {LEFT|RIGHT} [OUTER] JOIN}

table_reference   (b表)

ON conditional_expr  (连接条件)

 

(2)连接类型:

  (a)  INNER JOIN, 内连接: 在MySQL中, JOIN, CROSS JOIN 和 INNER JOIN 是等价的, 一般习惯使用INNER JOIN

    内连接:显示左表和右表中交集的部分、公共的部分,即仅显示符合连接条件的记录

 

 

    (b)  LEFT [OUTER] JOIN, 左外连接

     显示左表的全部记录及右表符合连接条件的记录

右表中没有符合条件的记录则显示为NULL

 

 

    (c)  RIGHT [OUTER] JOIN, 右外连接

显示右表的全部记录以及左表符合连接条件的记录,左表中不符合连接条件的显示为NULL

 

(3) 数据表参照:

  table_reference 

  tbl_name [ [AS] alias ] | table_subquery [AS] alias

  数据表可以使用tbl_name AS alias_name 或 tbl_name alias_name赋予别名 (两张不同的表中可能存在相同的字段,为了区分)

  table_subquery可以作为子查询使用在FROM子句中,这样的子查询必须为其赋予别名 

 

(4) 连接条件: 使用ON关键字来设定连接条件,也可以使用WHERE来代替

                   通常使用ON关键字来设定连接条件,使用WHERE关键字进行结果集记录的过滤。

 

(5) 多表连接:

 

【表的连接其实可以说是外键的逆向操作,外键把数据分开存储,连接又将多张表联系在一起】

 

(6) 关于连接的几点说明:

 (a)

A LEFT JOIN B join_condition  (左外连接,右外连接同理)

数据表B的结果集依赖数据表A ;(数据表A中有的记录在B表中才显示出来,否则B表中记录不能显示)

数据表A的结果集根据左连接条件依赖所有数据表(B表除外);

左外连接条件决定如何检索数据表B(在没有指定WHERE条件的情况下);(A表决定B表)

如果数据表A的某条记录符合WHERE条件,但是在数据表B不存在符合连接条件的记录,将生成一个所有列为空(NULL)的额外的B行。

 

(b) 如果使用内连接查找的记录在连接数据表中不存在,并且在WHERE子句中尝试以下操作: col_name IS NULL时, 如果col_name被定义为NOT NULL, MySQL将在找到符合连接条件的记录后停止搜索更多的行

 

 

 

 

[参考链接]   https://www.imooc.com/learn/122  

 

 

 

 

 

 

 

 

 

原文地址:https://www.cnblogs.com/jade-91/p/8682165.html