zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    Gridview如何用自定义按钮进行编辑和提交修改
    winform多线程中给datagridview绑定数据源
    DevExpress控件WebchartControl的学习记录
    datagridview右键选中单元格并获取到焦点
    asp.net局部页面打印,以及如何去掉打印时自动保留的URL地址(页眉页脚)
    GridView如何实现点击某行的指定列弹出新窗体
    C# Color Font 与String之间的转换
    推荐一款 asp.net js日历控件
    js浮点运算替代函数
    VSeWss 1.3 CTP 安装后出现错误
  • 原文地址:https://www.cnblogs.com/feiyujinghong/p/6639882.html
Copyright © 2011-2022 走看看