SQL 子查询1
1. 定义
编程之家解释:子
,又称嵌套,是一种嵌套在其它 的 Where 字句中的。
2. 前言
本小节,我们将一起学习 子
。
子是一种复杂的方式,一般子语句都可以被分为主部分和子部分。子部分为主部分服务,常用于为主返回其所需数据,或者进一步筛选主数据。
子的知识点其实不多,学习它的难点在于如何将 使用熟练,然后灵活搭配,本小节我们将聚焦在子的基本使用上,而把子中的两个 ANY 和 ALL 放在下一小节介绍。
本小节测试数据如下,请先在中执行:
DROP TABLE IF EXISTS imooc_user;CREATE TABLE imooc_user( id int PRIMARY KEY, username varchar(), age int, int);INSERT INTO imooc_user(id,username,age,) VALUES (,'peter', , ),(,'pedro', , ),(,'jerry', , ),(,'mike', , ),(,'tom', , );
3. 语法
子的语法其实与普通的语法没有什么区别,只不过多了相应的子部分。
以 Select 为例,语法如下:
SELECT [col] FROM [table_name]WHERE [col] [operator]( SELECT [col] FROM [table_name]; WHERE [col] [operator] );
其中table_name
表示数据表,col
表示字段名,operator
表示字段操作。
子可灵活用于 Insert、Select、Update 和 Delete 指令中,我们没有列举出所有的语法,它们在子的部分其实是一致的,区别在于主操作部分。
子虽然很灵活,但是也有一定的限制,它必须满足以下几个规则:
子必须在括号()内。
子中不能使用 Order By,主可以使用。
子不能使用在聚合中。
Between 指令不能与子一起使用,但可使用在子内部。
子若返回一条记录,则只能使用单值运算符,如 > ,若返回多条记录需使用多值运算符,如 In。
若子返回多条记录,且使用 ANY 或 ALL ,则可使用单值比较符,我们将在下小节介绍。
4. Select 中的子
在 Select 中使用子是最为常见的一种子方式,子让我们可以更加灵活数据。
请书写 语句,imooc_user
表中小于最大年龄的。
分析:
从题干中得出,需要小于最大年龄的,所以第一步需要找到最大年龄
,然后通过最大年龄比较得出年龄小于它的;使用子可以的办到这一点,子得到最大年龄,主部分以最大年龄作为筛选条件从而得到结果。
语句:
整理可得语句如下:
SELECT username FROM imooc_user WHERE age <(SELECT age FROM imooc_user ORDER BY age DESC LIMIT );
结果如下:
+----------+ | username | +----------+ | peter | | pedro | | mike | | tom | +----------+
imooc_user 表中,jerry 年龄最大,28 岁,结果中了除他以外的所有人, 因此结果正确。
5. Insert 中的子
子还可以与 Insert 搭配使用,Insert 可将子得到的数据插入到其它表中。
请书写 语句,imooc_user
表中小于最大年龄的,并将插入到 username_copy
表中。
分析:
同上,另外的我们还需要新建 username_copy 表,并向其中插入数据。
语句:
整理可得语句如下:
CREATE TABLE username_copy(username varchar());INSERT INTO username_copy SELECT username FROM imooc_user WHERE age <(SELECT age FROM imooc_user ORDER BY age DESC LIMIT );
username_copy 表信息如下:
+----------+ | username | +----------+ | peter | | pedro | | mike | | tom | +----------+
6. Update 中的子
子可搭配 Update,一次完成多条记录的更新,当然也可只更新一条记录。
请书写 语句,将imooc_user
表中年龄大于 25 岁的积分 100 。
分析:
由题干可知,我们可分两步
完成,第一步从子中年龄大于 25 岁的 id,然后在主操作语句部分更新他们的积分。
语句:
整理可得语句如下:
UPDATE imooc_user SET = + WHERE id IN (SELECT id FROM imooc_user WHERE age > );
更新后,积分如下:
+----------+-------+ | username | | +----------+-------+ | peter | 100 | | pedro | 200 | | jerry | 600 | | mike | 300 | | tom | 1100 | +----------+-------+
如果你使用 ,那么上面语句会无法执行,因为 在同一张表中又更新,因此我们可以使用如下的方式来改写 ,使 来:
UPDATE imooc_user SET = + WHERE id IN ( SELECT .id FROM(SELECT id FROM imooc_user WHERE age > ) as );
7. Delete 中的子
子可与 Delete 搭配使用来更加方便数据。
请书写 语句,imooc_user
表中积分大于 500 的 。
分析:
我们仍然分两步完成,第一步子积分大于 500 的 id,然后在主操作他们。
语句:
整理可得语句如下:
DELETE FROM imooc_user WHERE id IN (SELECT id FROM imooc_user WHERE > );
成功后,imooc_user 表信息如下:
+----------+-------+ | username | | +----------+-------+ | peter | 100 | | pedro | 200 | | mike | 300 | +----------+-------+
同样的, 在一张表中同时和,因此我们改写一下:
DELETE FROM imooc_user WHERE id IN ( SELECT a.id FROM (SELECT id FROM imooc_user WHERE > 500) as a );
8. 小结
子的难点在于如何熟练搭配和使用,这是积少成多
的过程,因此请务必多多练习。
子也有诸多限制,而且不高,因此如果可以用一次的问题尽量不要使用子。