子查询和多表更新

使用的表和数据 点此

一、子查询

1、子查询嵌套在查询的内部,在圆括号内部
2、子查询可以包括关键字
3、子查询返回的结果可以为一个集合,只是需配合ANY 、SOME、ALL关键字使用
4、外层查询(此处的‘查询’是指所有SQL语句)可以是 SELECT INSERT UPDATE SET DO 等等。

e.g.1 查询goods_price 在平均值之上数据

方法一:普通方法

SELECT ROUND(AVG(goods_price),2) FROM tdb_goods;
#查到当前表tdb_goods的goods_price的平均值,只取了两位小数,得到的值为5626.36
SELECT goods_id,goods_name, goods_price FROM tdb_goods WHERE goods_price 
>=5626.36;

得到的结果如图:


子查询和多表更新_第1张图片

方法二:子查询

SELECT goods_id,goods_name, goods_price FROM tdb_goods WHERE goods_price 
>= (SELECT ROUND(AVG(goods_price),2)  FROM tdb_goods);

得到相同的结果

e.g.2 查询goods_price 大于超级本的其它记录--使用ANY 、SOME、ALL关键字

①、ANY和 > 结合,只要大于子查询的任意一条记录即可,即查询大于最小值的记录

SELECT * FROM tdb_goods WHERE goods_price > ANY
(SELECT goods_price FROM tdb_goods WHERE goods_cate = '超级本');

得到如图:

子查询和多表更新_第2张图片
ANY与 > 结合

②、ALL和 > 的结合,大于所有子查询的所有记录,即必须大于子查询的最大一条记录

SELECT * FROM tdb_goods WHERE goods_price > ALL 
(SELECT goods_price FROM tdb_goods WHERE goods_cate = '超级本');

得到如图:

ALL与 > 结合

其实使用ANY和SOME是相同的,具体的效果如下图:


子查询和多表更新_第3张图片
e.g.3 [NOT] IN 关键字

注: =ANY 与 IN 相同,<>ALL或!=ALL 与 NOT IN 相同

SELECT * FROM tdb_goods WHERE goods_price IN 
(SELECT goods_price FROM tdb_goods WHERE goods_cate = '超级本');
e.g.4 由于tdb_goods的goods_cate 有太多重复字段,故将其提取非重复字段为表tdb_goods_cate,并设置外键

创建表tdb_goods_cate:

CREATE TABLE IF NOT EXISTS tdb_goods_cate(
cate_id SMALLINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
cate_name VARCHAR(20) NOT NULL
);

使用子查询插入数据:

INSERT INTO tdb_goods_cate(cate_name) 
SELECT goods_cate FROM tdb_goods GROUP BY goods_cate;

得到如下效果:


子查询和多表更新_第4张图片
tdb_goods_cate插入数据

二、多表更新

e.g.1 继续上述e.g.4 ,尽管将非重复字段插入了表tdb_goods_cate, 但是表tdb_goods的goods_cate依然没有变化,现在要参照表tdb_goods_cate修改goods_cate字段

UPDATE tdb_goods INNER JOIN tdb_goods_cate 
ON goods_cate = cate_name SET goods_cate = cate_id;

其实使用上述方法一共经过了三步:
|---创建表tdb_goods_cate
|---将非重复的goods_cate字段值写入表tdb_goods_cate的cate_name
|---进行表tdb_goods的更新

多表更新一步到位 :CREATE...SELECT...

CREATE TABLE tdb_goods_brand (
brand_id SMALLINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
brand_name VARCHAR(40)
)
SELECT brand_name FROM tdb_goods GROUP BY brand_name;

可得到:


子查询和多表更新_第5张图片
tdb_goods_brand插入数据

再更新tdb_goods的brand_name:
由于两张表中的字段都为brand_name,故会出现如下错误:

Error Code: 1052. Column 'brand_name' in field list is ambiguous

所以可以将表明直接写到字段之前,但最常用的是给表起别名:

UPDATE tdb_goods AS g INNER JOIN tdb_goods_brand AS b ON g.brand_name = b.brand_name 
SET g.brand_name = b.brand_id;

完善tdb_goods表,修改字段brand_name 和字段goods_cate分别为brand_id 和cate_id,且都为SMALLINT:

ALTER TABLE tdb_goods 
CHANGE COLUMN brand_name brand_id SMALLINT UNSIGNED NOT NULL,
CHANGE COLUMN goods_cate cate_id SMALLINT UNSIGNED NOT NULL;

e.g.4和e.g.1做完后表tdb_goods变为:


子查询和多表更新_第6张图片
表tdb_goods的表结构

子查询和多表更新_第7张图片
表tdb_goods的部分数据

你可能感兴趣的:(子查询和多表更新)