sql同比环比计算
題目:有兩個表
表一:銷售明細
表二:產(chǎn)品明細
需求:查詢2020年,每月的銷售額,以及同比環(huán)比,并按照年月進行升序排序
思路:分步操作
獲得每月的數(shù)據(jù)
首先的抽取時間,以及獲得每個月的銷售額,要有 銷售額,兩個表肯定是要連接起來的
------- 獲取時間
YEAR(字段名)—獲取年份
MONTH(字段名)----獲取時間
SELECT YEAR(s.sail_time) 年, MONTH(s.sail_time) 月 , SUM(s.number*p.pro_price) 銷售額 FROM sail_info s LEFT JOIN produce_detail p ON s.produce_id=p.produce_id GROUP BY YEAR(s.sail_time) , MONTH(s.sail_time)
此處使用左連接的原因:是要補充銷售表里單品的價格,要以左表為基準,要用了左連接
結(jié)果:
單步操作獲得同比數(shù)據(jù)
同比:一般情況下是今年第n月與去年第n月比
計算方式:同比增長率=(本期數(shù)-同期數(shù))÷同期數(shù)×100%
所以要有個本期數(shù)據(jù)與同期數(shù)據(jù)一一對應(yīng)的表,那就要本期數(shù)據(jù)與同期數(shù)據(jù)分離
有了第一步之后很容易獲得數(shù)據(jù)
本期數(shù)據(jù):
SELECT YEAR(s.sail_time) 年, MONTH(s.sail_time) 月 , SUM(s.number*p.pro_price) 銷售額 FROM sail_info s LEFT JOIN produce_detail p ON s.produce_id=p.produce_id where YEAR(s.sail_time)=2020 GROUP BY YEAR(s.sail_time) , MONTH(s.sail_time)
同期數(shù)據(jù):
SELECT YEAR(s.sail_time) 年, MONTH(s.sail_time) 月 , SUM(s.number*p.pro_price) 銷售額 FROM sail_info s LEFT JOIN produce_detail p ON s.produce_id=p.produce_id where YEAR(s.sail_time)=2019 GROUP BY YEAR(s.sail_time) , MONTH(s.sail_time)
下面就要進行表的關(guān)聯(lián)了
本期、同期的區(qū)別就是年份不一樣,月份一樣唄,那就用月份作為連接點進行連接,代碼和結(jié)果截圖如下,同比就完成了~
計算的是本期,本期數(shù)據(jù)是關(guān)鍵所以這邊進行的是右連接—因為本期數(shù)據(jù)放在右邊,放左邊用左連接就好了
ps:如果覺得這邊跳了步驟的話可以將查詢結(jié)果改成 * 先去查看關(guān)聯(lián)之后的表
SELECT CONCAT(e,'-',a) 年月, b 月銷售額,
CASE WHEN d>0 THEN CONCAT((b-d)/d*100,'%') -- 轉(zhuǎn)化為百分比,此處考慮到銷售額為0的情況,分母不能為0,用case進行了條件判斷
ELSE "同期沒有數(shù)據(jù)" END 同比
-- 這邊的文字可以 換掉
FROM
(SELECT YEAR(s.sail_time) f , MONTH(s.sail_time) c , SUM(s.number*p.pro_price) d FROM sail_info s LEFT JOIN produce_detail p
ON s.produce_id=p.produce_id WHERE YEAR(s.sail_time)=2019 GROUP BY MONTH(s.sail_time)) s2
RIGHT JOIN
(SELECT YEAR(s.sail_time) e,MONTH(s.sail_time) a , SUM(s.number*p.pro_price) b FROM sail_info s LEFT JOIN produce_detail p
ON s.produce_id=p.produce_id WHERE YEAR(s.sail_time)=2020 GROUP BY MONTH(s.sail_time)) s1
ON s1.a=s2.c
3.單步操作獲得環(huán)比數(shù)據(jù)
環(huán)比:一般是指報告期水平與前一時期水平之比,此處指本月數(shù)據(jù)與上月數(shù)據(jù)
計算方式:環(huán)比增長速度=(本期數(shù)-上期數(shù))÷上期數(shù)×100%
肯定也是要有表的關(guān)聯(lián)了唄,怎么連呢???
既然是計算2020年的環(huán)比,那就以要計算的為基礎(chǔ)數(shù)據(jù),進行表的關(guān)聯(lián)
上面已經(jīng)有全部的年份、月份對應(yīng)的數(shù)據(jù),這一步主要是進行表的關(guān)聯(lián)
兩個表進行關(guān)聯(lián):
-1 2020年數(shù)據(jù)的表,即判斷條件設(shè)置年份為2020的查詢結(jié)果表
-2 考慮到2020年一月份對應(yīng)的是2019年的12月份,所以這個張表是不加判斷條件的表,包含了2019年和2020年數(shù)據(jù)的表
SELECT * FROM (SELECT YEAR(s.sail_time) e,MONTH(s.sail_time) a , SUM(s.number*p.pro_price) 本期銷售額 FROM sail_info s LEFT JOIN produce_detail p ON s.produce_id=p.produce_id WHERE YEAR(s.sail_time)=2020 GROUP BY MONTH(s.sail_time)) s1 LEFT JOIN (SELECT YEAR(s.sail_time) f, MONTH(s.sail_time) g, SUM(s.number*p.pro_price) 上期銷售額 FROM sail_info s LEFT JOIN produce_detail p ON s.produce_id=p.produce_id GROUP BY MONTH(s.sail_time),YEAR(s.sail_time)) s3 ON ((s1.a-1)=s3.g AND s1.e=s3.f) OR (s1.a=1 AND s3.g=12 AND s3.f=2019)
解析以下這個:
(s1.a-1)=s3.g AND s1.e=s3.f
這個是針對2020年2月份的數(shù)據(jù),2020 02-06 的數(shù)據(jù)與2020 01-05的數(shù)據(jù)一一對應(yīng)
按關(guān)聯(lián)前的,a(月份)和g(月份)應(yīng)該是相等的,因為對比的是上一期的,所以要錯開,大的減掉等與小的
那一月份怎么辦呢??
s1.a=1 AND s3.g=12 AND s3.f=2019
這邊就不能用上面的辦法了,跨年了,所以需要用and連接的方式進行限制,而且需要限定為2019年的12月份,這邊因為數(shù)據(jù)比較少,不限定年份也沒問題
兩個部分用 or 并列存在,兩個條件要分別用括號括起來,否則這個查詢條件等于沒有。。。。
把* 換成
CONCAT(e,'-',a) 年月,f 月銷售額,
CASE WHEN h>0 THEN CONCAT((b-h)/h*100,'%')
ELSE "上期沒有數(shù)據(jù)" END 環(huán)比
執(zhí)行查詢:
最后一步,將數(shù)據(jù)放到一個表里~
通過上述說明,可以發(fā)現(xiàn)都關(guān)聯(lián)了2020年數(shù)據(jù)查詢的表,所以可以將這個表放在中間 ,三個表進行關(guān)聯(lián)(也是操作同比數(shù)據(jù)用右連接的原因)
CASE WHEN d>0 THEN CONCAT((b-d)/d*100,'%')
ELSE "同期沒有數(shù)據(jù)" END 同比 ,
CASE WHEN h>0 THEN CONCAT((b-h)/h*100,'%')
ELSE "上期沒有數(shù)據(jù)" END 環(huán)比
FROM
(SELECT MONTH(s.sail_time) c , SUM(s.number*p.pro_price) d ,YEAR(s.sail_time) ye FROM sail_info s LEFT JOIN produce_detail p
ON s.produce_id=p.produce_id WHERE YEAR(s.sail_time)=2019 GROUP BY MONTH(s.sail_time)) s2
RIGHT JOIN
(SELECT MONTH(s.sail_time) a , SUM(s.number*p.pro_price) b ,YEAR(s.sail_time) e FROM sail_info s LEFT JOIN produce_detail p
ON s.produce_id=p.produce_id WHERE YEAR(s.sail_time)=2020 GROUP BY MONTH(s.sail_time)) s1
ON s1.a=s2.c
LEFT JOIN
(SELECT YEAR(s.sail_time) f, MONTH(s.sail_time) g, SUM(s.number*p.pro_price) h FROM sail_info s LEFT JOIN produce_detail p
ON s.produce_id=p.produce_id GROUP BY MONTH(s.sail_time),YEAR(s.sail_time)) s3 ON ((s1.a-1)=s3.g AND s1.e=s3.f) OR
(s1.a=1 AND s3.g=12 AND s3.f=2019) ORDER BY CONCAT(e,'-',a)
總結(jié)
- 上一篇: linux扩充单个路径下的内存,超详尽!
- 下一篇: linux7 无法连接网络,CentOS