我要做的是,做一个月统计页面,如下:
如图可看出,就是每月的总交易量的一个统计,再计算出同比,环比。
在网上看了很多,都说用left join,刚开始也是学着用。现在总结的话,就
要想清楚,为什么用left join ? 打个比方,如果客户选择2017-04 至 2017-07 那么有可能这段时间内是没数据的,那也要显示出来,就是0嘛。所以这个时间段内每月不一定有数据的情况下,就要用left join了,因为月份是肯定存在的,只是数据有没有就不知道了。这里要建一个日期表。创建方式如下:
CREATE TABLE bdt_date (
RepDate date NOT NULL,
RepYear int(8) DEFAULT NULL,
RepMonth int(8) DEFAULT NULL,
RepDay int(8) DEFAULT NULL,
RepWeek int(8) DEFAULT NULL,
PRIMARY KEY (RepDate)
);
CREATE PROCEDURE getAllDate(num int)
BEGIN
DECLARE count INT DEFAULT 0;
DECLARE startDay DATE DEFAULT DATE(NOW());
DECLARE endDay DATE DEFAULT DATE(NOW());
WHILE count<num DO
INSERT INTO bdt_date(RepDate,RepYear,RepMonth,RepDay,RepWeek,RepYearMonth) VALUES (startDay,YEAR(startDay),MONTH(startDay),DAY(startDay),WEEKOFYEAR(startDay),);
SET count=count+1;
SET startDay=DATE_ADD(DATE(NOW()),INTERVAL count DAY);
SET endDay=DATE_SUB(DATE(NOW()),INTERVAL count DAY);
INSERT INTO bdt_date(RepDate,RepYear,RepMonth,RepDay,RepWeek,RepYearMonth) VALUES (endDay,YEAR(endDay),MONTH(endDay),DAY(endDay),WEEKOFYEAR(endDay));
END WHILE;
END
那sql我也放出来,如果能帮到大家就很开心了。极力欢迎大神指教,优化sql,也确实有点长。
select
DISTINCT DATE_FORMAT(date.RepDate,'%Y-%m') as yearMonth,
CASE WHEN t1.totalTransaction IS NULL OR t1.totalTransaction = 0
THEN 0
ELSE t1.totalTransaction END as totalTransaction,
CASE WHEN t1.totalVolumes IS NULL OR t1.totalVolumes = 0
THEN 0
ELSE t1.totalVolumes END as totalVolumes,
CASE WHEN t1.totalTransactionMoney IS NULL OR t1.totalTransactionMoney = 0
THEN 0
ELSE t1.totalTransactionMoney END as totalTransactionMoney,
CASE WHEN t1.totalVolumesMoney IS NULL OR t1.totalVolumesMoney = 0
THEN 0
ELSE t1.totalVolumesMoney END as totalVolumesMoney,
CASE WHEN t1.increasePrice IS NULL OR t1.increasePrice = 0
THEN 0
ELSE t1.increasePrice END as increasePrice,
CASE WHEN t1.totalAbortive IS NULL OR t1.totalAbortive = 0
THEN 0
ELSE t1.totalAbortive END as totalAbortive,
CASE WHEN t2.totalTransaction = 0 OR t2.totalTransaction IS NULL
THEN '---'
ELSE CONCAT(round(((t1.totalTransaction-t2.totalTransaction) / t2.totalTransaction) * 100,2) , '%') END AS totalTransactionProportionT,
CASE WHEN t3.totalTransaction = 0 OR t3.totalTransaction IS NULL
THEN '---'
ELSE CONCAT(round(((t1.totalTransaction-t3.totalTransaction) / t3.totalTransaction) * 100,2) , '%') END AS totalTransactionProportionH,
CASE WHEN t2.totalVolumes = 0 OR t2.totalVolumes IS NULL
THEN '---'
ELSE CONCAT(round(((t1.totalVolumes-t2.totalVolumes) / t2.totalVolumes) * 100,2) , '%') END AS totalVolumesProportionT,
CASE WHEN t3.totalVolumes = 0 OR t3.totalVolumes IS NULL
THEN '---'
ELSE CONCAT(round(((t1.totalVolumes-t3.totalVolumes) / t3.totalVolumes) * 100,2) , '%') END AS totalVolumesProportionH,
CASE WHEN t2.totalTransactionMoney = 0 OR t2.totalTransactionMoney IS NULL
THEN '---'
ELSE CONCAT(round(((t1.totalTransactionMoney-t2.totalTransactionMoney) / t2.totalTransactionMoney) * 100,2), '%') END AS totalTransactionMoneyProportionT,
CASE WHEN t3.totalTransactionMoney = 0 OR t3.totalTransactionMoney IS NULL
THEN '---'
ELSE CONCAT(round(((t1.totalTransactionMoney-t3.totalTransactionMoney) / t3.totalTransactionMoney) * 100,2), '%') END AS totalTransactionMoneyProportionH,
CASE WHEN t2.totalVolumesMoney = 0 OR t2.totalVolumesMoney IS NULL
THEN '---'
ELSE CONCAT(round(((t1.totalVolumesMoney-t2.totalVolumesMoney) / t2.totalVolumesMoney) * 100,2), '%') END AS totalVolumesMoneyProportionT,
CASE WHEN t3.totalVolumesMoney = 0 OR t3.totalVolumesMoney IS NULL
THEN '---'
ELSE CONCAT(round(((t1.totalVolumesMoney-t3.totalVolumesMoney) / t3.totalVolumesMoney) * 100,2), '%') END AS totalVolumesMoneyProportionH,
CASE WHEN t1.totalVolumes IS NULL OR t1.totalTransaction IS NULL OR t1.totalTransaction = 0
THEN '---'
ELSE CONCAT(round((t1.totalVolumes / t1.totalTransaction) *100,2), '%' ) END AS volumesPercent
from bdt_date date
left join
(select
DATE_FORMAT(price.end_time,'%Y-%m') as t1_yearMonth,
sum(item.TRADING_WEIGHT) as totalTransaction,
sum(case when price.state = "6" then item.TRADING_WEIGHT else 0 end) as totalVolumes,
sum(case when batch.OFFER_TYPE = "2" then price.STARTING_PIRCE else (price.STARTING_PIRCE * item.TRADING_WEIGHT) end) as totalTransactionMoney,
sum(case when price.state = "6" then
case batch.OFFER_TYPE when "2" then price.STARTING_PIRCE
when "1" then (price.STARTING_PIRCE * item.TRADING_WEIGHT) end
else 0 end) as totalVolumesMoney,
sum(case when price.state = "6" then
case batch.OFFER_TYPE when "2" then (price.CURRENT_PRICE - price.STARTING_PIRCE)
when "1" then (item.TRADING_WEIGHT * (price.CURRENT_PRICE - price.STARTING_PIRCE)) end
else 0 end) as increasePrice,
sum(case when price.state = "7" then item.TRADING_WEIGHT else 0 end) as totalAbortive
from bdt_resources_item item,bdt_price_info price,bdt_batch batch
where
batch.id = price.batch_id and
item.id = price.item_id and
price.state in ("6","7")
group by DATE_FORMAT(price.end_time,'%Y-%m')) as t1
on DATE_FORMAT(date.RepDate,'%Y-%m') = t1.t1_yearMonth
left join
(select
DATE_FORMAT(DATE_ADD(price2.end_time,INTERVAL 1 YEAR),'%Y-%m') as yearMonth,
sum(item2.TRADING_WEIGHT) as totalTransaction,
sum(case when price2.state = "6" then item2.TRADING_WEIGHT else 0 end) as totalVolumes,
sum(case when batch2.OFFER_TYPE = "2" then price2.STARTING_PIRCE else (price2.STARTING_PIRCE * item2.TRADING_WEIGHT) end) as totalTransactionMoney,
sum(case when price2.state = "6" then
case batch2.OFFER_TYPE when "2" then price2.STARTING_PIRCE
when "1" then (price2.STARTING_PIRCE * item2.TRADING_WEIGHT) end
else 0 end) as totalVolumesMoney
from bdt_resources_item item2,bdt_price_info price2,bdt_batch batch2
where
batch2.id = price2.batch_id and
item2.id = price2.item_id and
price2.state in ("6","7")
group by DATE_FORMAT(price2.end_time,'%Y-%m')) as t2
on DATE_FORMAT(date.RepDate,'%Y-%m')= t2.yearMonth
left join
(select
DATE_FORMAT(DATE_ADD(price3.end_time,INTERVAL 1 MONTH),'%Y-%m') as yearMonth,
sum(item3.TRADING_WEIGHT) as totalTransaction,
sum(case when price3.state = "6" then item3.TRADING_WEIGHT else 0 end) as totalVolumes,
sum(case when batch3.OFFER_TYPE = "2" then price3.STARTING_PIRCE else (price3.STARTING_PIRCE * item3.TRADING_WEIGHT) end) as totalTransactionMoney,
sum(case when price3.state = "6" then
case batch3.OFFER_TYPE when "2" then price3.STARTING_PIRCE
when "1" then (price3.STARTING_PIRCE * item3.TRADING_WEIGHT) end
else 0 end) as totalVolumesMoney
from bdt_resources_item item3,bdt_price_info price3,bdt_batch batch3
where
batch3.id = price3.batch_id and
item3.id = price3.item_id and
price3.state in ("6","7")
group by DATE_FORMAT(price3.end_time,'%Y-%m')) as t3
on DATE_FORMAT(date.RepDate,'%Y-%m')= t3.yearMonth
where
date.RepDate >=#{beginDate} and
date.RepDate <=#{endDate}
在这过程中,也熟练掌握了 CASE... WHEN ... ELSE ... END 用法,很开心。
还有一个呢,跟这个类似,多了一个分组条件,就是每月每个客户的统计
sql如下
select
DISTINCT DATE_FORMAT(date.RepDate,'%Y-%m') as yearMonth,
t1.member_name as memberName,
CASE WHEN t1.totalTransaction IS NULL OR t1.totalTransaction = 0
THEN 0
ELSE t1.totalTransaction END as totalTransaction,
CASE WHEN t1.totalVolumes IS NULL OR t1.totalVolumes = 0
THEN 0
ELSE t1.totalVolumes END as totalVolumes,
CASE WHEN t1.totalTransactionMoney IS NULL OR t1.totalTransactionMoney = 0
THEN 0
ELSE t1.totalTransactionMoney END as totalTransactionMoney,
CASE WHEN t1.totalVolumesMoney IS NULL OR t1.totalVolumesMoney = 0
THEN 0
ELSE t1.totalVolumesMoney END as totalVolumesMoney,
CASE WHEN t1.increasePrice IS NULL OR t1.increasePrice = 0
THEN 0
ELSE t1.increasePrice END as increasePrice,
CASE WHEN t1.totalAbortive IS NULL OR t1.totalAbortive = 0
THEN 0
ELSE t1.totalAbortive END as totalAbortive,
CASE WHEN t2.totalTransaction = 0 OR t2.totalTransaction IS NULL
THEN '---'
ELSE CONCAT(round(((t1.totalTransaction-t2.totalTransaction) / t2.totalTransaction) * 100,2) , '%') END AS totalTransactionProportionT,
CASE WHEN t3.totalTransaction = 0 OR t3.totalTransaction IS NULL
THEN '---'
ELSE CONCAT(round(((t1.totalTransaction-t3.totalTransaction) / t3.totalTransaction) * 100,2) , '%') END AS totalTransactionProportionH,
CASE WHEN t2.totalVolumes = 0 OR t2.totalVolumes IS NULL
THEN '---'
ELSE CONCAT(round(((t1.totalVolumes-t2.totalVolumes) / t2.totalVolumes) * 100,2) , '%') END AS totalVolumesProportionT,
CASE WHEN t3.totalVolumes = 0 OR t3.totalVolumes IS NULL
THEN '---'
ELSE CONCAT(round(((t1.totalVolumes-t3.totalVolumes) / t3.totalVolumes) * 100,2) , '%') END AS totalVolumesProportionH,
CASE WHEN t2.totalTransactionMoney = 0 OR t2.totalTransactionMoney IS NULL
THEN '---'
ELSE CONCAT(round(((t1.totalTransactionMoney-t2.totalTransactionMoney) / t2.totalTransactionMoney) * 100,2), '%') END AS totalTransactionMoneyProportionT,
CASE WHEN t3.totalTransactionMoney = 0 OR t3.totalTransactionMoney IS NULL
THEN '---'
ELSE CONCAT(round(((t1.totalTransactionMoney-t3.totalTransactionMoney) / t3.totalTransactionMoney) * 100,2), '%') END AS totalTransactionMoneyProportionH,
CASE WHEN t2.totalVolumesMoney = 0 OR t2.totalVolumesMoney IS NULL
THEN '---'
ELSE CONCAT(round(((t1.totalVolumesMoney-t2.totalVolumesMoney) / t2.totalVolumesMoney) * 100,2), '%') END AS totalVolumesMoneyProportionT,
CASE WHEN t3.totalVolumesMoney = 0 OR t3.totalVolumesMoney IS NULL
THEN '---'
ELSE CONCAT(round(((t1.totalVolumesMoney-t3.totalVolumesMoney) / t3.totalVolumesMoney) * 100,2), '%') END AS totalVolumesMoneyProportionH,
CASE WHEN t1.totalVolumes IS NULL OR t1.totalTransaction IS NULL OR t1.totalTransaction = 0
THEN '---'
ELSE CONCAT(round((t1.totalVolumes / t1.totalTransaction) *100,2), '%' ) END AS volumesPercent
from bdt_date date
left join
(select
DATE_FORMAT(price.end_time,'%Y-%m') as t1_yearMonth,
batch.member_code,
batch.member_name,
sum(item.TRADING_WEIGHT) as totalTransaction,
sum(case when price.state = "6" then item.TRADING_WEIGHT else 0 end) as totalVolumes,
sum(case when batch.OFFER_TYPE = "2" then price.STARTING_PIRCE else (price.STARTING_PIRCE * item.TRADING_WEIGHT) end) as totalTransactionMoney,
sum(case when price.state = "6" then
case batch.OFFER_TYPE when "2" then price.STARTING_PIRCE
when "1" then (price.STARTING_PIRCE * item.TRADING_WEIGHT) end
else 0 end) as totalVolumesMoney,
sum(case when price.state = "6" then
case batch.OFFER_TYPE when "2" then (price.CURRENT_PRICE - price.STARTING_PIRCE)
when "1" then (item.TRADING_WEIGHT * (price.CURRENT_PRICE - price.STARTING_PIRCE)) end
else 0 end) as increasePrice,
sum(case when price.state = "7" then item.TRADING_WEIGHT else 0 end) as totalAbortive
from bdt_resources_item item,bdt_price_info price,bdt_batch batch
where
batch.id = price.batch_id and
item.id = price.item_id and
price.state in ("6","7")
group by DATE_FORMAT(price.end_time,'%Y-%m'),batch.member_code) as t1
on DATE_FORMAT(date.RepDate,'%Y-%m') = t1.t1_yearMonth
left join
(select
DATE_FORMAT(DATE_ADD(price2.end_time,INTERVAL 1 YEAR),'%Y-%m') as yearMonth,
batch2.member_code,
sum(item2.TRADING_WEIGHT) as totalTransaction,
sum(case when price2.state = "6" then item2.TRADING_WEIGHT else 0 end) as totalVolumes,
sum(case when batch2.OFFER_TYPE = "2" then price2.STARTING_PIRCE else (price2.STARTING_PIRCE * item2.TRADING_WEIGHT) end) as totalTransactionMoney,
sum(case when price2.state = "6" then
case batch2.OFFER_TYPE when "2" then price2.STARTING_PIRCE
when "1" then (price2.STARTING_PIRCE * item2.TRADING_WEIGHT) end
else 0 end) as totalVolumesMoney
from bdt_resources_item item2,bdt_price_info price2,bdt_batch batch2
where
batch2.id = price2.batch_id and
item2.id = price2.item_id and
price2.state in ("6","7")
group by DATE_FORMAT(price2.end_time,'%Y-%m'),batch2.member_code) as t2
on DATE_FORMAT(date.RepDate,'%Y-%m')= t2.yearMonth
left join
(select
DATE_FORMAT(DATE_ADD(price3.end_time,INTERVAL 1 MONTH),'%Y-%m') as yearMonth,
batch3.member_code,
sum(item3.TRADING_WEIGHT) as totalTransaction,
sum(case when price3.state = "6" then item3.TRADING_WEIGHT else 0 end) as totalVolumes,
sum(case when batch3.OFFER_TYPE = "2" then price3.STARTING_PIRCE else (price3.STARTING_PIRCE * item3.TRADING_WEIGHT) end) as totalTransactionMoney,
sum(case when price3.state = "6" then
case batch3.OFFER_TYPE when "2" then price3.STARTING_PIRCE
when "1" then (price3.STARTING_PIRCE * item3.TRADING_WEIGHT) end
else 0 end) as totalVolumesMoney
from bdt_resources_item item3,bdt_price_info price3,bdt_batch batch3
where
batch3.id = price3.batch_id and
item3.id = price3.item_id and
price3.state in ("6","7")
group by DATE_FORMAT(price3.end_time,'%Y-%m'),batch3.member_code) as t3
on DATE_FORMAT(date.RepDate,'%Y-%m')= t3.yearMonth
where
date.RepDate >=#{beginDate} and
date.RepDate <=#{endDate} and
t1.member_code IS NOT NULL
<if test="companycode != null and companycode != ''">
and t1.member_code = #{companycode}
</if>
group by date.RepDate,t1.member_code