使用的表和数据 点此
一、子查询
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;
得到的结果如图:
方法二:子查询
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 = '超级本');
得到如图:
②、ALL和 > 的结合,大于所有子查询的所有记录,即必须大于子查询的最大一条记录
SELECT * FROM tdb_goods WHERE goods_price > ALL
(SELECT goods_price FROM tdb_goods WHERE goods_cate = '超级本');
得到如图:
其实使用ANY和SOME是相同的,具体的效果如下图:
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;
得到如下效果:
二、多表更新
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;
可得到:
再更新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变为: