sql同比環比計算


題目:有兩個表
表一:銷售明細

 表二:產品明細

需求:查詢2020年,每月的銷售額,以及同比環比,並按照年月進行升序排序

思路:分步操作

  1. 獲得每月的數據
    首先的抽取時間,以及獲得每個月的銷售額,要有 銷售額,兩個表肯定是要連接起來的
    ------- 獲取時間
    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)  

此處使用左連接的原因:是要補充銷售表里單品的價格,要以左表為基准,要用了左連接
結果:

  1. 單步操作獲得同比數據
    同比:一般情況下是今年第n月與去年第n月比
    計算方式:同比增長率=(本期數-同期數)÷同期數×100%
    所以要有個本期數據與同期數據一一對應的表,那就要本期數據與同期數據分離
    有了第一步之后很容易獲得數據
    本期數據:
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)  

 同期數據:

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)  

下面就要進行表的關聯了
本期、同期的區別就是年份不一樣,月份一樣唄,那就用月份作為連接點進行連接,代碼和結果截圖如下,同比就完成了~
計算的是本期,本期數據是關鍵所以這邊進行的是右連接—因為本期數據放在右邊,放左邊用左連接就好了
ps:如果覺得這邊跳了步驟的話可以將查詢結果改成 * 先去查看關聯之后的表

SELECT  CONCAT(e,'-',a) 年月, b 月銷售額, 
CASE WHEN d>0 THEN CONCAT((b-d)/d*100,'') -- 轉化為百分比,此處考慮到銷售額為0的情況,分母不能為0,用case進行了條件判斷
     ELSE "同期沒有數據" 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.單步操作獲得環比數據
環比:一般是指報告期水平與前一時期水平之比,此處指本月數據與上月數據
計算方式:環比增長速度=(本期數-上期數)÷上期數×100%
肯定也是要有表的關聯了唄,怎么連呢???
既然是計算2020年的環比,那就以要計算的為基礎數據,進行表的關聯
上面已經有全部的年份、月份對應的數據,這一步主要是進行表的關聯
兩個表進行關聯:
-1 2020年數據的表,即判斷條件設置年份為2020的查詢結果表
-2 考慮到2020年一月份對應的是2019年的12月份,所以這個張表是不加判斷條件的表,包含了2019年和2020年數據的表

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月份的數據,2020 02-06 的數據與2020 01-05的數據一一對應
按關聯前的,a(月份)和g(月份)應該是相等的,因為對比的是上一期的,所以要錯開,大的減掉等與小的
那一月份怎么辦呢??

s1.a=1 AND s3.g=12 AND s3.f=2019

這邊就不能用上面的辦法了,跨年了,所以需要用and連接的方式進行限制,而且需要限定為2019年的12月份,這邊因為數據比較少,不限定年份也沒問題

兩個部分用 or 並列存在,兩個條件要分別用括號括起來,否則這個查詢條件等於沒有。。。。
把* 換成

CONCAT(e,'-',a) 年月,f 月銷售額, 
 CASE WHEN h>0 THEN CONCAT((b-h)/h*100,'')
     ELSE "上期沒有數據" END 環比

執行查詢:

  1. 最后一步,將數據放到一個表里~
    通過上述說明,可以發現都關聯了2020年數據查詢的表,所以可以將這個表放在中間 ,三個表進行關聯(也是操作同比數據用右連接的原因)
CASE WHEN d>0 THEN CONCAT((b-d)/d*100,'')
     ELSE "同期沒有數據" END 同比 , 
 CASE WHEN h>0 THEN CONCAT((b-h)/h*100,'')
     ELSE "上期沒有數據" END 環比
 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) 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM