mysql进行sum多个表多个字段的时候数据很大的问题的解决以及6表联合复杂结构查询

首先要说明一点,这是一个非常复杂的数据结构,对于精通mysql的人来说,理解很好理解.但是可能还有更大的速度提升空间.

这种涉及到6个表的查询,使用一句话来完成,7000多商品,总数据量应该是十万级,200毫秒应该还是可以接受了.毕竟使用的rds性能也不是特别好.

而且多个表在一句话里面来进行查询的话,有助于练习mysql思维而且灵动性比较好.视图多是很方便写语句,但是效率有时候非常低.

本文主要着重于解决如下问题,都是属于个人笔记

1 如何用一条语句执行多个表的联合查询并提升效率

2 多个表联合查询的时候,sum函数数字很大不准确的问题解决,比如表a,b,c 都有字段需要进行sum统计的错误结果解决

3 left join 的使用

 

用到的表有:

1.商品信息表

2.出库明细表

3.出库单表

4.入库明细表

5.入库单表

6.每次盘点情况的信息表

商品媒体信息表

 

解决如下需求:

1 一条语句罗列并统计出来:itemid,name,imgurl,incount,outcount,hascount,outpopolaration

分别意思为 商品编号,名称,图片url,本阶段总出库数量,本阶段总出库数量,本阶段出库商品的流行度

信息分别来源于:

商品表,商品表,商品媒体信息表,入库明细表,出库明细表,临时创建的表,出库信息表

其中有没展示数据的表为:盘点信息表,入库单表,出库单表.   这三个表都是做关联用的

另外上面提到一个 临时创建的表   有hascount 字段  其实不是表,而是直接用两个列的减法来做的.

 

先贴出来最终的查询语句

 

SELECT
	a.itemid,
	a.`name`,
	d.filepath AS imgurl,
	c.incount,
	b.outcount,
	(c.incount - b.outcount) AS hascount,
	b.outpopularation
FROM
	iteminfo a
LEFT JOIN (
	(
		SELECT
			outstockbilldetial.itemid,
			sum(outstockbilldetial.count) AS outcount,
			ifnull(count(*) ,- 1) AS outpopularation
		FROM
			outstockbilldetial,
			outstockbill
		WHERE
			outstockbill.Time > (
				SELECT
					max(FinishTime)
				FROM
					ventorycheckbatchinfo
			)
		AND outstockbill.Canceled = 0
		AND outstockbill.OutStockBillId = outstockbilldetial.OutStockBillId
		GROUP BY
			itemid
	) AS b
	INNER JOIN (
		SELECT
			instockbilldetial.itemid,
			ifnull(
				sum(instockbilldetial.count),
				0
			) AS incount
		FROM
			instockbilldetial,
			instockbill
		WHERE
			instockbill.Time > (
				SELECT
					max(FinishTime)
				FROM
					ventorycheckbatchinfo
			)
		AND instockbill.Canceled = 0
		AND instockbill.InStockBillId = instockbilldetial.InStockBillId
		GROUP BY
			itemid
	) AS c ON b.itemid = c.itemid
) ON a.itemid = b.itemid
LEFT JOIN itemmediainfo AS d ON a.itemid = d.itemid
GROUP BY
	a.itemid
ORDER BY
	hascount ASC

 

 

再贴出来最后的查询结果 

 

然后 我们发现 查询的数据中,有的是有入库没有出库的,那么连入库记录都看不到了,也自然看不到实际的库存了.这怎么办?

 把入库记录挪到前面去. 这样就能保证商品和入库记录都有,然后虽然有的商品入库了没出库,那也离统计出来更进一步了

SELECT
	a.itemid,
	a.`name`,
	d.filepath AS imgurl,
	c.incount,
	b.outcount,
	(c.incount - b.outcount) AS hascount,
	b.outpopularation
FROM
	iteminfo a
LEFT JOIN (
		SELECT
			instockbilldetial.itemid,
			ifnull(
				sum(instockbilldetial.count),
				0
			) AS incount
		FROM
			instockbilldetial,
			instockbill
		WHERE
			instockbill.Time > (
				SELECT
					max(FinishTime)
				FROM
					ventorycheckbatchinfo
			)
		AND instockbill.Canceled = 0
		AND instockbill.InStockBillId = instockbilldetial.InStockBillId
		GROUP BY
			itemid
	) AS c ON a.itemid = c.itemid

LEFT JOIN (
	(
		SELECT
			outstockbilldetial.itemid,
			ifnull(sum(outstockbilldetial.count),-1000) AS outcount,
			ifnull(count(*),-1000) AS outpopularation
		FROM
			outstockbilldetial,
			outstockbill
		WHERE
			outstockbill.Time > (
				SELECT
					max(FinishTime)
				FROM
					ventorycheckbatchinfo
			)
		AND outstockbill.Canceled = 0
		AND outstockbill.OutStockBillId = outstockbilldetial.OutStockBillId
		GROUP BY
			itemid
	) AS b) on b.itemid = c.itemid
LEFT JOIN itemmediainfo AS d ON a.itemid = d.itemid

GROUP BY
	a.itemid
ORDER BY
	outpopularation ASC

再次进行改善以后,出库如果是没有没有记录的话,也不影响hascount也就是剩余库存的统计

另外 popularation 字段,如果是没有出库过的,就标记为-1

总记录条数 7820条 改善后  0.23秒

 

 

然后如果我们查询商品有库存但是没有出库记录的  

我们加一下where查询条件即可

where 
(
        c.incount - ifnull(b.outcount, 0)
    ) >0

 

 

然后我们再根据拥有库存的多少,来排序一下滞销品

SELECT
	a.itemid,
	a.`name`,
	d.filepath AS imgurl,
	c.incount,
	b.outcount,
	(
		c.incount - ifnull(b.outcount, 0)
	) AS hascount,
	ifnull(b.outpopularation, - 1) AS popularation
FROM
	iteminfo a
LEFT JOIN (
	SELECT
		instockbilldetial.itemid,
		ifnull(
			sum(instockbilldetial.count),
			0
		) AS incount
	FROM
		instockbilldetial,
		instockbill
	WHERE
		instockbill.Time > (
			SELECT
				max(FinishTime)
			FROM
				ventorycheckbatchinfo
		)
	AND instockbill.Canceled = 0
	AND instockbill.InStockBillId = instockbilldetial.InStockBillId
	GROUP BY
		itemid
) AS c ON a.itemid = c.itemid
LEFT JOIN (
	(
		SELECT
			outstockbilldetial.itemid,
			ifnull(
				sum(outstockbilldetial.count) ,- 1000
			) AS outcount,
			ifnull(count(*) ,- 1000) AS outpopularation
		FROM
			outstockbilldetial,
			outstockbill
		WHERE
			outstockbill.Time > (
				SELECT
					max(FinishTime)
				FROM
					ventorycheckbatchinfo
			)
		AND outstockbill.Canceled = 0
		AND outstockbill.OutStockBillId = outstockbilldetial.OutStockBillId
		GROUP BY
			itemid
	) AS b
) ON b.itemid = c.itemid
LEFT JOIN itemmediainfo AS d ON a.itemid = d.itemid
WHERE
	(
		c.incount - ifnull(b.outcount, 0)
	) > 0
AND outpopularation IS NULL
GROUP BY
	a.itemid
ORDER BY
	hascount DESC

如果查询滞销的40条商品 加上 limit 40就可以了

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Afterwards_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值