MySQL中如何計算同比和環(huán)比
前言
今天在做數(shù)據(jù)建模的時候,ads層的需求中有個叫同比和環(huán)比的指標(biāo),這兩指標(biāo)的計算之前都沒有接觸過,經(jīng)過我兩三個小時的研究,終于搞明白什么是同比,什么是環(huán)比,如何使用Mysql來計算同比和環(huán)比。
我們先來看看什么是同比,什么是環(huán)比:
同比:通常是指今年第n月與去年第n月相比。同比發(fā)展速度主要是為了消除季節(jié)變動的影響,用以說明本期發(fā)展水平與去年同期發(fā)展水平對比而達到的相對發(fā)展速度。
環(huán)比:通常是指表示連續(xù)2個單位周期(比如連續(xù)兩月)內(nèi)的量的變化比。環(huán)比包括兩種:環(huán)比增長速度和環(huán)比發(fā)展速度。
那同比增長率和環(huán)比增長率又如何計算呢:
同比增長率:
同 比 增 長 率 = ( 本 期 數(shù) − 同 期 數(shù) ) / 同 期 數(shù) ∗ 100 %
環(huán)比增長率:
環(huán) 比 增 長 率 = ( 本 期 數(shù) − 上 期 數(shù) ) / 上 期 數(shù) × 100 %
同比和環(huán)比的區(qū)別
- 同比是本期與同期做對比,環(huán)比是本期與上期做對比。
- 環(huán)比一般是用在月、日很少用在年上,主要是對比很短時間內(nèi)漲幅程度,不過由于行業(yè)差異,比如旅游,會受到淡旺季影響。
- 同比一般用在相鄰兩年,相同時間段內(nèi),查看漲幅程度,一般用在兩年相同月份,很少用在兩月相同日期。
在MySQL中如何計算同比和環(huán)比
數(shù)據(jù)準(zhǔn)備
創(chuàng)建商品表并向商品表中添加數(shù)據(jù)
CREATE TABLE product (
`產(chǎn)品ID` varchar(20) NOT NULL,
`產(chǎn)品名稱` varchar(20) ,
`產(chǎn)品單價` int (10)
)
INSERT INTO product VALUES ('C1001','產(chǎn)品A',45);
INSERT INTO product VALUES ('C1002','產(chǎn)品B',52);
INSERT INTO product VALUES ('C1003','產(chǎn)品C',39);

創(chuàng)建訂單明細表并向訂單明細表中添加數(shù)據(jù)
CREATE TABLE sales (
`訂單ID` int NOT NULL PRIMARY KEY AUTO_INCREMENT,
`產(chǎn)品ID` varchar(25) NOT NULL ,
`銷售數(shù)量` int(20) ,
`銷售時間` timestamp(6) NULL DEFAULT NULL
);
INSERT INTO sales(`產(chǎn)品ID`,`銷售數(shù)量`,`銷售時間`) VALUES ('C1001', 15, '2020-06-01 10:10:12');
INSERT INTO sales(`產(chǎn)品ID`,`銷售數(shù)量`,`銷售時間`) VALUES ('C1002',26, '2020-05-02 0:10:12');
INSERT INTO sales (`產(chǎn)品ID`,`銷售數(shù)量`,`銷售時間`) VALUES ('C1003', 21, '2020-04-03 0:10:12');
INSERT INTO sales (`產(chǎn)品ID`,`銷售數(shù)量`,`銷售時間`) VALUES ('C1003', 23, '2020-04-04 0:10:12');
INSERT INTO sales (`產(chǎn)品ID`,`銷售數(shù)量`,`銷售時間`) VALUES ('C1003', 0, '2020-03-05 0:10:12');
INSERT INTO sales (`產(chǎn)品ID`,`銷售數(shù)量`,`銷售時間`) VALUES ('C1001', 16, '2020-02-06 3:0:12');
INSERT INTO sales (`產(chǎn)品ID`,`銷售數(shù)量`,`銷售時間`) VALUES ('C1002', 32, '2020-01-07 0:10:12');
INSERT INTO sales (`產(chǎn)品ID`,`銷售數(shù)量`,`銷售時間`) VALUES ('C1001', 16, '2019-12-08 0:12:24');
INSERT INTO sales (`產(chǎn)品ID`,`銷售數(shù)量`,`銷售時間`) VALUES ('C1001', 32, '2019-06-09 0:12:24');
INSERT INTO sales (`產(chǎn)品ID`,`銷售數(shù)量`,`銷售時間`) VALUES ('C1002', 17, '2019-05-09 0:12:24');

計算同比和環(huán)比
select year(c.銷售時間) yy,month(c.銷售時間) mm,
sum(c.銷售數(shù)量*d.產(chǎn)品單價) ss,
concat(ifnull(abs(round((sum(c.銷售數(shù)量*d.產(chǎn)品單價)-ss1)/ss1*100,2)),0),'%') 同比,
concat(ifnull(abs(round((sum(c.銷售數(shù)量*d.產(chǎn)品單價)-ss2)/ss2*100,2)),0),'%') 環(huán)比
from sales c
left join product d on c.產(chǎn)品ID=d.產(chǎn)品ID
left join (select month(a.銷售時間) mm1,
year(a.銷售時間) yy1,
sum(a.銷售數(shù)量*d.產(chǎn)品單價) ss1
from sales a
left join product d on a.產(chǎn)品ID=d.產(chǎn)品ID
GROUP BY mm1,yy1) a
on month(c.銷售時間) = a.mm1
and a.yy1 = year(c.銷售時間)-1
left join (select month(a.銷售時間) mm2,
year(a.銷售時間) yy2,
sum(a.銷售數(shù)量*d.產(chǎn)品單價) ss2
from sales a
left join product d on a.產(chǎn)品ID=d.產(chǎn)品ID
GROUP BY mm2,yy2) b
on (b.yy2 = year(c.銷售時間) and b.mm2+1 = month(c.銷售時間) OR (yy2=year(c.銷售時間)-1
AND b.mm2 = 12 AND month(c.銷售時間) = 1))
group by yy, mm
order by yy,mm asc
sql解析
select year(c.銷售時間) yy,month(c.銷售時間) mm,
sum(c.銷售數(shù)量*d.產(chǎn)品單價) ss,
# concat函數(shù),mysql字符串拼接,因為同比和環(huán)比都是百分?jǐn)?shù)
# ifnull函數(shù),mysql判斷字段是否為空,為空則為0
# abs函數(shù),mysql取絕對值,因為我這里取的都是正數(shù)
# round函數(shù),mysql保留幾位小數(shù)
concat(ifnull(abs(round((sum(c.銷售數(shù)量*d.產(chǎn)品單價)-ss1)/ss1*100,2)),0),'%') 同比,
concat(ifnull(abs(round((sum(c.銷售數(shù)量*d.產(chǎn)品單價)-ss2)/ss2*100,2)),0),'%') 環(huán)比
from sales c
left join product d on c.產(chǎn)品ID=d.產(chǎn)品ID
# 上一年銷售額
left join (select month(a.銷售時間) mm1,
year(a.銷售時間) yy1,
sum(a.銷售數(shù)量*d.產(chǎn)品單價) ss1
from sales a
left join product d on a.產(chǎn)品ID=d.產(chǎn)品ID
GROUP BY mm1,yy1) a
# 同比月份相同,年份減1
on month(c.銷售時間) = a.mm1
and a.yy1 = year(c.銷售時間)-1
# 今年銷售額
left join (select month(a.銷售時間) mm2,
year(a.銷售時間) yy2,
sum(a.銷售數(shù)量*d.產(chǎn)品單價) ss2
from sales a
left join product d on a.產(chǎn)品ID=d.產(chǎn)品ID
GROUP BY mm2,yy2) b
# 環(huán)比取數(shù)考慮到為一月的情況
on (b.yy2 = year(c.銷售時間) and b.mm2+1 = month(c.銷售時間) OR (yy2=year(c.銷售時間)-1
AND b.mm2 = 12 AND month(c.銷售時間) = 1))
group by yy, mm
order by yy,mm asc
結(jié)果:

除此之外,還想要計算累計銷售的話,可以這樣寫:
select year(銷售時間) yy,month(銷售時間) mm, sum(銷售數(shù)量*b.產(chǎn)品單價) over(order by year(銷售時間) ,month(銷售時間) ) 累計數(shù)量 from sales a left join product b on a.產(chǎn)品ID=b.產(chǎn)品ID order by yy,mm
同比和環(huán)比這塊的確不好計算
總結(jié)
到此這篇關(guān)于MySQL中如何計算同比和環(huán)比的文章就介紹到這了,更多相關(guān)MySQL計算同比和環(huán)比內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
解決MySQL數(shù)據(jù)庫鏈接超時報1129錯誤問題
MySQL?為了數(shù)據(jù)庫的安全性默認(rèn)在鏈接中斷或者錯誤時記錄錯誤鏈接的ip?等信息(host_cache),有點像系統(tǒng)的錯誤日志的一種機制,這篇文章主要介紹了MySQL數(shù)據(jù)庫鏈接超時報1129錯誤解決辦法,需要的朋友可以參考下2022-10-10
mysql一條sql查出多個條件不同的sum或count問題
這篇文章主要介紹了mysql一條sql查出多個條件不同的sum或count問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-05-05
MySQL創(chuàng)建和刪除數(shù)據(jù)表的命令及語法詳解
這篇文章主要介紹了MySQL創(chuàng)建和刪除數(shù)據(jù)表的命令及語法,是MySQL入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下2015-11-11

