mysql中update、delete、install尽量不要使用子查询

一、mysql查询的五种子句

        where(条件查询)、having(筛选)、group by(分组)、order by(排序)、limit(限制结果数)
 
       1、where常用运算符:
            比较运算符
                > ,  < ,=  , != (< >),>=   ,   <= 
                in(v1,v2..vn) 
                between v1 and v2    在v1至v2之间(包含v1,v2)
            逻辑运算符
                not ( ! )  逻辑非
                or ( || )    逻辑或
                and ( && )  逻辑与
 
                where price>=3000 and price <= 5000 or price >=500 and price <=1000
                取500-1000或者3000-5000的值
                where price not between 3000 and 5000
                不在3000与5000之间的值
 
            模糊查询
                like 像
                通配符:
                %  任意字符
                _   单个字符
                    where goods_name like '诺基亚%'
                    where goods_name like '诺基亚N__'
 
        2、group by 分组
                一般情况下group需与统计函数(聚合函数)一起使用才有意义
                如:select goods_id,goods_name,cat_id,max(shop_price) from goods group by cat_id;
                        这里取出来的结果中的good_name是错误的!因为shop_price使用了max函数,那么它是取最大的,而语句中使用了group by 分组,那么goods_name并没有使用聚合函数,它只是cat_id下的第一个商品,并不会因为shop_price改变而改变
                mysql中的五种统计函数:
                (1)max:求最大值
                    select max(goods_price) from goods
                      这里会取出最大的价格的值,只有值
                        #查询每个栏目下价格最高的
                        select cat_id,max(goods_price) from goos group by cat_id;
                        #查出价格最高的商品编号
                        select goods_id,max(goods_price) from goods group by goods_id;
                       
                       
                (2)min:求最小值
                (3)sum:求总数和
                        #求商品库存总和
                        select sum(goods_number) from goods;
                (4)avg:求平均值
                        #求每个栏目的商品平均价格
                        select cat_id,avg(goods_price) from goods group by cat_id;
                (5)count:求总行数
                        #求每个栏目下商品种类
                        select cat_id,count(*) from goods group by cat_id;
 
                   ###要把每个字段名当成变量来理解,它可以进行运算###
                        例:查询本店每个商品价格比市场价低多少;
                        select goods_id,goods_name,goods_price-market_price from goods;
                            查询每个栏目下面积压的货款
                        select cat_id,sum(goods_price*goods_number) from goods group by cat_id;
 
                    ###可以用as来给计算结果取个别名###
                        select cat_id,sum(goods_price * goods_number)  as hk from goods group by cat_id
                        不仅列名可以取别名,表单也可以取别名
 
            3、having 与where 的异同点
 
                    having与where类似,可以筛选数据,where后的表达式怎么写,having后就怎么写
                    where针对表中的列发挥作用,查询数据
                    having对查询结果中的列发挥作用,筛选数据
                    #查询本店商品价格比市场价低多少钱,输出低200元以上的商品
                    select goods_id,good_name,market_price - shop_price as s from goods having s>200 ;
                    //这里不能用where因为s是查询结果,而where只能对表中的字段名筛选
                    如果用where的话则是:
                    select goods_id,goods_name from goods where market_price - shop_price > 200;
 
                    #同时使用where与having
                    select cat_id,goods_name,market_price - shop_price as s from goods where cat_id = 3 having s > 200;
                    #查询积压货款超过2万元的栏目,以及该栏目积压的货款
                    select cat_id,sum(shop_price * goods_number) as t from goods group by cat_id having s > 20000
                    #查询两门及两门以上科目不及格的学生的平均分
                          思路:
                            #先计算所有学生的平均分
                             select name,avg(score) as pj from stu group by name;
                            #查出所有学生的挂科情况
                            select name,score<60 from stu;
                                    #这里score<60是判断语句,所以结果为真或假,mysql中真为1假为0
                            #查出两门及两门以上不及格的学生
                            select name,sum(score<60) as gk from stu group by name having gk > 1;
                            #综合结果
                            select name,sum(score<60) as gk,avg(score) as pj from stu group by name having gk >1;
                4、order by
                    (1) order by price  //默认升序排列
                    (2)order by price desc //降序排列
                    (3)order by price asc //升序排列,与默认一样
                    (4)order by rand() //随机排列,效率不高
                        #按栏目号升序排列,每个栏目下的商品价格降序排列
                        select * from goods where cat_id !=2 order by cat_id,price desc;
                5、limit
                    limit [offset,] N
                    offset 偏移量,可选,不写则相当于limit 0,N
                    N     取出条目
 
                    #取价格第4-6高的商品
                    select good_id,goods_name,goods_price from goods order by good_price desc limit 3,3;
                   
            ###查询每个栏目下最贵的商品
                思路:
                        #先对每个栏目下的商品价格排序
                        select cat_id,goods_id,goods_name,shop_price from goods order by cat_id,shop_price desc;
                        #上面的查询结果中每个栏目的第一行的商品就是最贵的商品
                        #把上面的查询结果理解为一个临时表[存在于内存中]【子查询】
                        #再从临时表中选出每个栏目最贵的商品
                        select * from (select goods_id,goods_name,cat_id,shop_price from goods order by cat_id,shop_price desc) as t group by cat_id;
                        #这里使用group by cat_id是因为临时表中每个栏目的第一个商品就是最贵的商品,而group by前面没有使用聚合函数,所以默认就取每个分组的第一行数据,这里以cat_id分组
 
                 良好的理解模型:
                    1、where后面的表达式,把表达式放在每一行中,看是否成立
                    2、字段(列),理解为变量,可以进行运算(算术运算和逻辑运算) 
                    3、 取出结果可以理解成一张临时表
  二、mysql子查询
        1、where型子查询
                (把内层查询结果当作外层查询的比较条件)
                #不用order by 来查询最新的商品
                select goods_id,goods_name from goods where goods_id = (select max(goods_id) from goods);
                #取出每个栏目下最新的产品(goods_id唯一)
                select cat_id,goods_id,goods_name from goods where goods_id in(select max(goods_id) from goods group by cat_id);
 
        2、from型子查询
                (把内层的查询结果供外层再次查询)
                #用子查询查出挂科两门及以上的同学的平均成绩
                    思路:
                        #先查出哪些同学挂科两门以上
                        select name,count(*) as gk from stu where score < 60 having gk >=2;
                        #以上查询结果,我们只要名字就可以了,所以再取一次名字
                        select name from (select name,count(*) as gk from stu having gk >=2) as t;
                        #找出这些同学了,那么再计算他们的平均分
                        select name,avg(score) from stu where name in (select name from (select name,count(*) as gk from stu having gk >=2) as t) group by name;
 
        3、exists型子查询
                (把外层查询结果拿到内层,看内层的查询是否成立)
                #查询哪些栏目下有商品,栏目表category,商品表goods
                    select cat_id,cat_name from category where exists(select * from goods where goods.cat_id = category.cat_id);
   三、union的用法
              (把两次或多次的查询结果合并起来,要求查询的列数一致,推荐查询的对应的列类型一致,可以查询多张表,多次查询语句时如果列名不一样,则取第一次的列名!如果不同的语句中取出的行的每个列的值都一样,那么结果将自动会去重复,如果不想去重复则要加all来声明,即union all)
           ## 现有表a如下
                id  num
                a    5
                b    10
                c    15
                d    10
            表b如下
                id  num
                b    5
                c    10
                d    20
                e    99
            求两个表中id相同的和
           select id,sum(num) from (select * from ta union select * from tb) as tmp group by id;
            //以上查询结果在本例中的确能正确输出结果,但是,如果把tb中的b的值改为10以查询结果的b的值就是10了,因为ta中的b也是10,所以union后会被过滤掉一个重复的结果,这时就要用union all
            select id,sum(num) from (select * from ta union all select * from tb) as tmp group by id;
               
            #取第4、5栏目的商品,按栏目升序排列,每个栏目的商品价格降序排列,用union完成
            select goods_id,goods_name,cat_id,shop_price from goods where cat_id=4 union select goods_id,goods_name,cat_id,shop_price from goods where cat_id=5 order by cat_id,shop_price desc;
            【如果子句中有order by 需要用( ) 包起来,但是推荐在最后使用order by,即对最终合并后的结果来排序】
            #取第3、4个栏目,每个栏目价格最高的前3个商品,结果按价格降序排列
             (select goods_id,goods_name,cat_id,shop_price from goods where cat_id=3 order by shop_price desc limit 3) union  (select goods_id,goods_name,cat_id,shop_price from goods where cat_id=4 order by shop_price desc limit 3) order by shop_price desc;
           
    四、左连接,右连接,内连接
 
                现有表a有10条数据,表b有8条数据,那么表a与表b的笛尔卡积是多少?
                    select * from ta,tb   //输出结果为8*10=80条
                 
            1、左连接
               以左表为准,去右表找数据,如果没有匹配的数据,则以null补空位,所以输出结果数>=左表原数据数
 
                语法:select n1,n2,n3 from ta left join tb on ta.n1= ta.n2 [这里on后面的表达式,不一定为=,也可以>,<等算术、逻辑运算符]【连接完成后,可以当成一张新表来看待,运用where等查询
                 #取出价格最高的五个商品,并显示商品的分类名称
                select goods_id,goods_name,goods.cat_id,cat_name,shop_price from goods left join category on goods.cat_id = category.cat_id order by  shop_price desc limit 5;       
           2、右连接
                a left join b 等价于 b right join a
                推荐使用左连接代替右连接
                语法:select n1,n2,n3 from ta right join tb on ta.n1= ta.n2
           3、内连接
                查询结果是左右连接的交集,【即左右连接的结果去除null项后的并集(去除了重复项)】
                mysql目前还不支持 外连接(即左右连接结果的并集,不去除null项)
                语法:select n1,n2,n3 from ta inner join tb on ta.n1= ta.n2
        #########
                 例:现有表a
                        name  hot
                         a        12
                         b        10
                         c        15
                    表b:
                        name   hot
                          d        12
                          e        10
                          f         10
                          g        8
                    表a左连接表b,查询hot相同的数据
                    select a.*,b.* from a left join b on a.hot = b.hot
                    查询结果:
                        name  hot   name  hot
                          a       12     d       12
                          b       10     e       10
                          b       10     f        10
                          c       15     null    null
                    从上面可以看出,查询结果表a的列都存在,表b的数据只显示符合条件的项目       
                      再如表b左连接表a,查询hot相同的数据
                        select a.*,b.* from b left join a on a.hot = b.hot
                        查询结果为:
                        name  hot   name  hot
                          d       12     a       12
                          e        10    b       10
                          f        10     b      10
                          g        8     null    null
                    再如表a右连接表b,查询hot相同的数据
                        select a.*,b.* from a right join b on a.hot = b.hot
                        查询结果和上面的b left join a一样
                ###练习,查询商品的名称,所属分类,所属品牌
                    select goods_id,goods_name,goods.cat_id,goods.brand_id,category.cat_name,brand.brand_name from goods left join category on goods.cat_id = category.cat_id left join brand on goods.brand_id = brand.brand_id limit 5;

Mysql子查询、关联查询的更多相关文章

  1. MySQL如何执行关联查询

    MySQL中‘关联(join)’ 一词包含的意义比一般意义上理解的要更广泛.总的来说,MySQL认为任何一个查询都是一次‘关联’ --并不仅仅是一个查询需要到两个表的匹配才叫关联,索引在MySQL中, ...

  2. Mysql多表表关联查询 inner Join left join right join

    Mysql多表表关联查询 inner Join left join right join

  3. mysql如何执行关联查询与优化

    mysql如何执行关联查询与优化 一.前言 在数据库中执行查询(select)在我们工作中是非常常见的,工作中离不开CRUD,在执行查询(select)时,多表关联也非常常见,我们用的也比较多,那么m ...

  4. Mysql 单表查询 子查询 关联查询

    数据准备: ## 学院表create table department( d_id int primary key auto_increment, d_name varchar(20) not nul ...

  5. JDBC MySQL 多表关联查询查询

    public static void main(String[] args) throws Exception{ Class.forName("com.mysql.jdbc.Driver&q ...

  6. MySQL 如何执行关联查询

    本文同时发表在https://github.com/zhangyachen/zhangyachen.github.io/issues/51 当前mysql执行的策略很简单:mysql对任何关联都执行嵌 ...

  7. MySQL多表关联查询与存储过程

    --  **************关联查询(多表查询)**************** -- 需求:查询员工及其所在部门(显示员工姓名,部门名称) -- 1.1 交叉连接查询(不推荐.产生笛卡尔乘积 ...

  8. MySQL 三种关联查询的方式: ON vs USING vs 传统风格

    看看下面三个关联查询的 SQL 语句有何区别? 1SELECT * FROM film JOIN film_actor ON (film.film_id = film_actor.film_id) 2 ...

  9. MySQL多表关联查询数量

    //多表关联查询数量select user, t1.count1, t2.count2from user tleft join ( select user_id, count(sport_type) ...

  10. 表单生成器(Form Builder)之mongodb表单数据查询——关联查询

    这一篇接着记录一下查询相关的操作.想象一下,如果想要在一张表格中展示某些车辆的耗损和营收情况,我们该怎么处理.车辆.耗损.营收各自存储在一张表中,耗损和营收中冗余了车辆信息……我们便想到了关联查询.m ...

随机推荐

  1. The "Real" Project Plan

    "I need a project plan by tomorrow morning." As project managers, that's what we hear. But ...

  2. C++经典编程题#4:单词翻转

    总时间限制:  1000ms  内存限制:  65536kB 描述 输入一个句子(一行),将句子中的每一个单词翻转后输出. 输入 只有一行,为一个字符串,不超过500个字符.单词之间以空格隔开. 输出 ...

  3. 将一个UIView对象的内容保存为UIImage

    + (UIImage*)imageFromView:(UIView*)view{ UIGraphicsBeginImageContextWithOptions(view.bounds.size, YE ...

  4. iOS:FFmpeg视频播放和直播框架

    视频直播和播放转码器框架 介绍: FFmpeg是一套可以用来记录.转换数字音频.视频,并能将其转化为流的开源计算机程序.采用LGPL或GPL许可证. 它提供了录制.转换以及流化音视频的完整解决方案.它 ...

  5. 私有IP地址范围

    私有IP地址范围 有一部分的地址专门是用于内网的地址,包括: A类中 10.0.0.0/8 B类中 172.16.0.0/12 ~ 172.31.0.0/12 C类中 192.168.0.0/16 这 ...

  6. passport 自动取密码

    django settings.py """ Django settings for password project. Generated by . For more ...

  7. SVG 参考手册

    1. SVG元素模块 Animation.Module animate animateColor animateTransform animateMotion set mpath 剪裁模块 clipP ...

  8. IIS应用程序池添加ASP.NET v4.0

    可能在安装.NET Framewrok 4.0之前,IIS就已经装好了,结果在IIS的应用程序池中只有.NET 2.0的Classic .NET AppPool和DefaultAppPool.在使用v ...

  9. javaScript常用工具库

    对应于百度前端技术学院2015年春季的课程2相关内容 https://github.com/baidu-ife/ife/tree/master/2015_spring/task/task0002 ht ...

  10. grunt搭建前端自动化实践

    grunt是什么? grunt是一个前端构建工具, 每种应用开发, 都有一套构建工具, 例如linux c程序开发, 构建工具是make, java程序的构建工具为maven,web前端经过十多年的发 ...