mysql高级语法

/**
 * @Author: PHP小枫哥
 * @Date:   2018-11-14 09:52:52
 * @Last Modified time: 2018-11-14 15:40:53
 * @tilte MySQL深入理解
 * @QQ群:902131929
 */

/*
 * orders 表(订单表)
 *   id    num  istate
 *   id:主键
 *   istate:状态
 *
 * sku 表(明细表)
 *   id orderid   nprice  num details
 *   id:主键
 *   orderid:外键
 *   nprice:单价
 *   num:数量
 *   details:描述
 *
 * batch 表(批次表)
 *   id   skuid   nprice  num 
 *   id:主键
 *   skuid:外键
 *   nprice:单价
 *   num:数量
 *
 * 订单表与明细表是一对多的关系
 * 明细表与批次表一对一的关系
 *
 */

/*<p>LEFT JOIN </p>*/

/*
左连接 以主表为准(个人称索引表)

订单表数据:
 id    num istate
 1      4    0
 2      4    1
 3      11   0

明细表数据:
id orderid   nprice  num details
 1   1          2      3   产品1
 2   1          1      1   产品2
 3   2          3      4   产品3   
 4   3          4      5   产品4
 5   3          5      6   产品5


select * from orders o left join sku on a.id=sku.orderid
这时候会出现 6条数据

select * from orders o left join sku on a.id=sku.orderid
这时候也会出现6条数据


因为是与索引表关联,索引表有的数据关联表没有就会出现null值的情况(查询所有数据才会看见)
可以理解成 索引表数据展示不变,其它表只是靠着对应关系依附进来,如果存在多对一的情况,会对应一一生成记录

right join同理

<p>INNER JOIN </p>

订单表数据:
 id    num istate
 1      4    0
 2      4    1
 3      11   0

明细表数据:
id orderid   nprice  num details
 1   1          2      3   产品1
 2   1          1      1   产品2
 3   2          3      4   产品3   
 4   3          4      5   产品4
 5   3          5      6   产品5

 select * from  orders o inner join sku on sku.orderid=o.id
 等价于
 select * from  sku  left join order o on sku.orderid=o.id where o.id is not null

 inner join 就是取交集,如果存在多对一的关系也会一一生成记录

<p>子查询 </p>

 查询订单表的状态和对应明细的详情和数量和单价

 select o.istate, from orders o left join (select orderid,details,num,nprice from sku) sku on sku.orderid=o.id

 这时候会出现重复的主键,因为明细表与订单表是多对一的关系,利用GROUP_CONCAT函数并分组一下即可得到想要的数据
  select o.*,GROUP_CONCAT(sku.details Separator ';'),GROUP_CONCAT(sku.num Separator ';') from orders o left  join (select orderid,details,num,nprice from sku) sku on sku.orderid=o.id GROUP BY id
  等价于
  select o.*,GROUP_CONCAT(sku.details),GROUP_CONCAT(sku.num) from orders o inner  join (select orderid,details,num,nprice from sku) sku on sku.orderid=o.id GROUP BY id

 <p>group_concat</p>

  group_concat( [DISTINCT]  要连接的字段   [Order BY 排序字段 ASC/DESC]   [Separator '分隔符'] )
  上面的例子

  CONCAT  函数用于将多个字符串连接成一个字符串

  select o.*,GROUP_CONCAT(sku.sku SEPARATOR '/') from orders o left  join (select orderid,concat(details,';',num,';',nprice) as sku from sku) sku on sku.orderid=o.id  GROUP BY id

<p>case when</p>

   case  
    when  条件
    when  条件
    else result
    end

    查询 状态为0的订单数据并计算其订单的平均单价
      select case when o.istate=0 then '未付款' else '付款' end as istate,sku.nprice from orders o inner  join (select orderid,avg(nprice) as nprice  from sku group by orderid) sku on sku.orderid=o.id 
      等价于
       select o.id,case when o.istate=0 then '未付款' else '付款' end as istate,avg(nprice) as nprice from orders o inner  join  sku on sku.orderid=o.id  GROUP BY o.id  


<p>ifnull</p>

    IFNULL(expr1,expr2)如果 expr1 不是 NULL,IFNULL() 返回 expr1,否则它返回 expr2
    查询 状态不为0的订单数据

    select * from orders where ifnull(istate,'')!='0';(考虑到null值的情况)

<p>group by</p>

这里重点理解一下 group by

group by 你要看什么数据都必须在group by里面(个人理解)
  
  查询订单表的明细个数和不同单价个数:

  2种思路查询一种是以索引表为主,其它数据依附上来,索引表的所有数据都能看见,一种是直接分组只能看个别数据
  select * from orders o left join (select orderid,count(id) as num1,count(DISTINCT nprice) as num2 from sku group by orderid) sku on sku.orderid=o.id
  等价于
  select o.num,o.id,count(o.id) as num1,count(DISTINCT nprice) as num2 from orders o inner join  sku on sku.orderid=o.id  group by o.id
  这时候的num数据是随机取的,它并不在group by 里面


DATE_FORMAT(date,format)函数用于以不同的格式显示日期/时间数据

/********根据其它表更新数据************

根据批次表把明细表对应的数量更新
update sku  inner join batch set sku.num=batch.ipcs where sku.id=batch.skuid

将明细表的数量更新为批次表中的总数量
update sku set num=(select sum(ipcs) as ipcs from batch)

/********根据其它表插入数据************
往sku表插入数据 数据源来自batch表

insert into sku (orderid,nprice,num,details) select '11',price,ipcs,'描述' from batch  where skuid>0

猜你喜欢

转载自blog.csdn.net/qq_39586877/article/details/85164770