/**
* @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