• 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

  • 相关阅读:
    cogs 826. [Tyvj Feb11] GF打dota 次短路详细原创讲解! dijkstra
    cogs 2450. 距离 树链剖分求LCA最近公共祖先 快速求树上两点距离 详细讲解 带注释!
    cogs 647. [Youdao2010] 有道搜索框 Trie树 字典树
    cogs 293. [NOI 2000] 单词查找树 Trie树字典树
    P4550 收集邮票
    P1850 换教室 期望dp
    洛谷 UVA11021 Tribles
    P3802 小魔女帕琪 概率与期望
    P3369 【模板】普通平衡树 01Trie树
    P2765 魔术球问题
  • 原文地址:https://www.cnblogs.com/feiyujinghong/p/6639882.html
Copyright © 2020-2023  润新知