mysql中exists的详细说明

之前碰到了一道题,下面简要说明一下:

表结构如下:

CREATE TABLE `testa` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`cid` int(11) DEFAULT NULL comment ‘产品ID‘,
`uid` int(11) DEFAULT NULL comment ‘用户ID‘,
`buytime` int(11) DEFAULT NULL comment ‘购买时间‘,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf-8;

采用如下sql,随机插入一批测试数据:

INSERT into testa (cid,uid,buytime) values (rand()*5,rand()*5,rand()*10000);

说明:rand()返回0到1的随机小数,例如:0.4578285091163856,由于上表几个字段均为int类型在数据库存储时会自动进行四舍五入取整存储。

好了,下面进入正题:在该表内查出每个产品最早购买该产品的三个客户ID。描述好简单的一道题,当时难住了博主,经过多方查询资料,终于搞到了正确答案:

select * from testa as a where NOT EXISTS (select * from testa as b where a.cid = b.cid and a.buytime < b.buytime group by b.cid HAVING count(*) > 2);

这里最关键的几个个关键方法,exists 、 group by 和 having;

按照单个理解:exists为判断括号里面表达式返回结果是否为真,返回真则将当前主表的数据取出,否则放弃取出该结果(博主写该片文章时只了解这么多,还未深入)NOT EXISTS和EXISTS作用互斥,不做过多解释。

group by 不用过多解释,即将当前查询结果按照某个字段进行分组,去重。

having 的作用是将mysql执行完毕的最终结果进行二次处理的方法。

先说一下刚拿到这条sql的时候百思不得其解,认为exists应该和in的功能类似,先执行括号里面的方法,得到全部结果之后返回给主表进行二次查询,但是group by 之后的数据条件根本不能满足,最终还是求助于万能的因特奈特,终于明白该条sql得处理过程了,如下说明 :

因为group by 是要在where条件之后才会执行,所以会先执行子查询 中a表和b表的where关联查询,执行完where条件之后返回true,所以exists会执行为真。

这里说明一下exists执行过程:首先在a表拿第一条数据和b表的所有数据进行关联,得到所有大于当前a表查询数据的购买时间的b表数据,按照b表的产品进行分组,并且count(*)会记住当前结果获取到的行数,虽然having这时候还未生效;然后执行a表第二条数据,依次循环执行完a表所有数据之后,通过having进行结果整理,将所有查询行数大于2的全部抛弃(NOT EXISTS),得到最终结果。

说明:因为我们要取最早的三个客户,所以购买时间越小排名越高,并且当执行第一早客户的时候,a.buytime < b.buytime该条件count(*) 返回结果为0。

重新整理后sql可以这么写:select * from testa as b where EXISTS (select * from testa as c where c.cid = b.cid and b.buytime <= c.buytime group by c.cid HAVING count(*) <= 3);

借阅文章地址:

http://blog.csdn.net/qsyzb/article/details/12523051

http://fucheng.blog.51cto.com/2404495/1575693

时间: 2024-10-25 02:03:20

mysql中exists的详细说明的相关文章

MySQL 中 EXISTS 的用法

在MySQL中 EXISTS 和 IN 的用法有什么关系和区别呢? 假定数据库中有两个表 分别为 表 a 和表 b create table a ( a_id int, a_name varchar(20) ) create table b ( b_id int, b_name varchar(20) ) 那么 select * from a where a_name in (select b_name from b) 这条SQL语句的意义很明显是选取满足where条件下 a 中的所有列的数据

关于MySQL 中 EXISTS 的用法

在MySQL中 EXISTS 和 IN 的用法有什么关系和区别呢? 假定数据库中有两个表 分别为 表 a 和表 b create table a ( a_id int, a_name varchar(20) ) create table b ( b_id int, b_name varchar(20) ) 那么 select * from a where a_name in (select b_name from b) 这条SQL语句的意义很明显是选取满足where条件下 a 中的所有列的数据

003 mysql中exists的使用

mysql中exists可以使用在两个地方,一个是在创建库或者表的时候,配合if 使用,一个是在子查询中. # 和if一起使用,对库或表都可以使用 create database if not exists yaco charset utf8; drop database if exists yaco; # 在子查询中使用,返回True或者False,条件满足时执行前面的代码 select * from tb1 where exists(select id from tb2 where name

浅析MySQL中exists与in的使用

exists对外表用loop逐条查询,每次查询都会查看exists的条件语句,当 exists里的条件语句能够返回记录行时(无论记录行是的多少,只要能返回),条件就为真,返回当前loop到的这条记录,反之如果exists里的条 件语句不能返回记录行,则当前loop到的这条记录被丢弃,exists的条件就像一个bool条件,当能返回结果集则为true,不能返回结果集则为 false 如下: select * from user where exists (select 1); 对user表的记录逐

MySQL中exists和in的区别及使用场景

exists和in的使用方式: select * from A where exists (select * from B where A.id=B.id); select * from A where A.id in (select id from B); 1.exists是对外表做loop循环,每次loop循环再对内表(子查询)进行查询,那么是对内表的查询使用的索引,而外表有多大都需要遍历,不可避免,故内表大的使用exists,可加快效率: 2.in是把外表和内表做hash连接,先查询内表,

【转】MySQL中EXISTS的用法

原文链接:https://www.cnblogs.com/qlqwjy/p/8598091.html 比如在Northwind数据库中有一个查询为 SELECT c.CustomerId,CompanyName FROM Customers c WHERE EXISTS( SELECT OrderID FROM Orders o WHERE o.CustomerID=c.CustomerID) 这里面的EXISTS是如何运作呢?子查询返回的是OrderId字段,可是外面的查询要找的是Custom

MySQL中数学公式的详细方法 —— 【常用于人数、个数】

MySQL> count 统计行的数量,可查知共多少条数据 sum 统计列的数量 AVG 统计列的平均值 max 搜索列的最大值 mid 从文本提取字符 ucase 把字母全部替换为大写 Lcase 把字母全部替换为小写 应用方式> 例: SELECT AVG (age) FROM table

mysql中游标在存储过程中的详细用法

昨天写的一个东东,分享下给大家. drop PROCEDURE  if exists sp_cleanUserData; CREATE  PROCEDURE `sp_cleanUserData`() BEGIN /*定义游标*/ declare v_dt bigint(20) default 0 ; declare v_num INT DEFAULT 0; /*游标循环到末尾时给定义的常量赋值*/ declare cur_userId   CURSOR FOR select  userId fr

MySql中in和exists效率

mysql中的in语句是把外表和内表作hash 连接,而exists语句是对外表作loop循环,每次loop循环再对内表进行查询.一直大家都认为exists比in语句的效率要高,这种说法其实是不准确的.这个是要区分环境的. 如果查询的两个表大小相当,那么用in和exists差别不大. 如果两个表中一个较小,一个是大表,则子查询表大的用exists,子查询表小的用in: 例如:表A(小表),表B(大表) 1: select * from A where cc in (select cc from