mysql中的子查询的知识_MySQL 中的三种子查询

本篇开始是子查询的学习笔记,首先是一道题目:

查出最新的(goods_id 最大)的一条商品,比较简单,按照 order by 降序排列然后 limit 1即可:

select goods_id,goods_name,shop_price from goods order by goods_id desc limit 1;

where 型子查询

如果上面那个题目多了一个要求,不能用排序。这样子做比较难。如果再加一个条件,最大的 goods_id 就是 33,那么就可以这样写:

select goods_id,goods_name,shop_price from goods where goods_id = 33;

但是这个做法不具有通用性,增加或者删除数据以后,可能就不能查出正确结果。问题的关键就在于怎么知道最大的 goods_id ,前面的学习知道,用统计函数可以查到最大的 goods_id:

select max(goods_id) from goods

这句语句的返回值始终是指向最大的 goods_id。把这两句结合起来:

select goods_id,goods_name,shop_price from goods where goods_id = (select max(goods_id) from goods);

就像在变成语言中,先把查出来最大的 goods_id 赋值给中间变量,再利用中间变量查询

如果需要取出每个栏目下 goods_id 最大的商品信息,由于有多个栏目,所以 goods_id 也就形成了一个集合,所以需要用到 in :

select goods_id,goods_name,shop_price from goods where goods_id in (select max(goods_id) from goods group by cat_id);

where 型子查询,如果是 where 列 =(内层 sql) 则内层 sql 返回的必须是单行单列,单个值。

where 型子查询,如果是 where 列 in(内层 sql) 则内层 sql 返回的必须是单列,可以多行。

from 型子查询

在学习 from 子查询之前,需要理解一个概念:查询结果集在结构上可以当成表看,那就可以当成临时表对他进行再次查询:

取出每个栏目下 goods_id 最大的商品信息:

首先执行下面这句语句以后,能得到一个结果,其中每个栏目的第一行都是 goods_id 最大的行:

select goods_id,cat_id,goods_name from goods order by cat_id asc,goods_id desc;

假设存在这张表,表名叫 tmp ,那么:

select * from (select goods_id,cat_id,goods_name from goods order by cat_id asc,goods_id desc) as tmp group by cat_id;

不过上面这句语句在 8.0 或者某些 5.7版本中会报错。本段主要是为了理解 from 型子查询,实际业务中按照实际情况写语句即可,中心思想就是把结果当成表看,然后起一个别名。

exists 型子查询

exists 型子查询是指外层 sql 的结果,拿到内层 sql 去测试,如果内层 sql 成立,则该行取出。学习之前先建一张表:

create table category(

-> cat_id int auto_increment primary key,

-> cat_name varchar(20) not null default ''

-> )engine myisam;

向里面插入原来 ecshop.ecs_category 中的部分数据:

insert into test.category select cat_id,cat_name from ecshop.ecs_category;

取栏目表且只取出下面有商品的栏目表

那么假设某个栏目的 cat_id 为 N,则 select * from goods where cat_id = N如果能取出,则说明该栏目下有商品:

select cat_id,cat_name from category where exists (select * from goods where goods.cat_id=category.cat_id);

可以理解为,先把第一个 cat_id=1 取出来,带入到内层,那么内层就变成了:

select * from goods where goods.cat_id=1;

查询发现没有对应的值,返回 empty ,那么category 中 cat_id=1 这一行就不要了。接下来看 cat_id=2,代入,发现可以取出货物 goods 来,那么 category 中 cat_id=2 这一行就取出来

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MySQL的嵌套子查询和相关子查询在执行过程可能会导致不走索引的情况。下面分别介绍这两种子查询的执行过程。 1. 嵌套子查询的执行过程 嵌套子查询是指在一个查询语句嵌套了另一个查询语句。例如: ``` SELECT * FROM table1 WHERE column1 IN (SELECT column2 FROM table2 WHERE column3 = 'value'); ``` 在执行这条语句时,MySQL会先执行内部的子查询,得到一个结果集,然后再将这个结果集作为外部查询的条件,去匹配表1的数据。由于内部查询的结果集不是一个常量值,而是一个列表,因此MySQL无法使用索引来优化外部查询的执行。 如果内部查询返回的结果集很大,那么外部查询的性能就会受到影响。为了避免这种情况,可以使用关联查询来代替嵌套子查询: ``` SELECT * FROM table1 t1 JOIN table2 t2 ON t1.column1=t2.column2 WHERE t2.column3='value'; ``` 这样就可以避免嵌套子查询导致的性能问题。 2. 相关子查询的执行过程 相关子查询是指在一个查询语句嵌套了一个与外部查询相关的子查询。例如: ``` SELECT * FROM table1 WHERE column1 > (SELECT AVG(column2) FROM table2 WHERE column3 = 'value'); ``` 在执行这条语句时,MySQL会先执行内部的子查询,得到一个常量值,然后再将这个常量值作为外部查询的条件,去匹配表1的数据。由于内部查询返回的是一个常量值,而不是一个列表,因此MySQL可以使用索引来优化外部查询的执行。 然而,如果内部查询使用了与外部查询相关的字段,那么MySQL就无法使用索引来优化内部查询的执行。例如: ``` SELECT * FROM table1 WHERE column1 > (SELECT AVG(column2) FROM table2 WHERE column3 = table1.column4); ``` 在这个查询,内部查询的WHERE条件使用了外部查询的字段,因此MySQL无法使用索引来优化内部查询的执行。为了避免这种情况,可以使用JOIN来代替相关子查询: ``` SELECT t1.* FROM table1 t1 JOIN table2 t2 ON t1.column4=t2.column3 WHERE t1.column1 > AVG(t2.column2); ``` 这样就可以避免相关子查询导致的性能问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值