根据个人的需求,想在后端通过sequelize连接mysql中得到如下图所示结果,2022年1月份销量TOP10企业1年以来各月份的销量,
sql语句如下:
select 年份,月份,sum(case when 企业归并= '企业1' then 本月销量 end) '企业1',sum(case when 企业归并= '企业2' then 本月销量 end) '企业2',sum(case when 企业归并= '企业3' then 本月销量 end) '企业3',sum(case when 企业归并= '企业4' then 本月销量 end) '企业4',sum(case when 企业归并= '企业5' then 本月销量 end) '企业5',sum(case when 企业归并= '企业6' then 本月销量 end) '企业6',sum(case when 企业归并= '企业7' then 本月销量 end) '企业7',sum(case when 企业归并= '企业8' then 本月销量 end) '企业8',sum(case when 企业归并= '企业9' then 本月销量 end) '企业9',sum(case when 企业归并= '企业10' then 本月销量 end) '企业10' from 数据库 where 年份 in (2021,2022) and group by 年份,月份
想实现该结果,主要存在一个难点,就是TOP10企业并非固定,而是通过2022年1月份的销量排名得来的。通过SQL的自定义函数来获取结果是当然是一种解决方法,但是,既然是想在后端获取数据,在这里就采用node来进行配合实现以上表格:
const sql =`select 企业名称,sum(销量) 销量,ifnull((rank() over(order by sum(销量) desc),0) 排名 from 数据库 where 年份 =2022 and 月份=1 group by 企业名称`
const [results1, metadata1] = await sequelize.query(sql)
// results1 数据 其中的每个object都还有 企业名称,销量,排名三个key
const array1=results1.filter(
obj=>{return obj.排名<=10}
).map(
obj=>{return obj.企业名称}
) //array1 就是销量TOP10企业名称组成的数组
const array2=array1.map(
obj=>{return `,sum(case when 企业名称 = '${obj}' then 销量 end) '${obj}'`})
//array2 是一个由 sum语句字符串组成的数组
const text=_.join(array2, '') //通过lodash 工具将数组中的字符串拼接起来
const sql2=`select 年份,月份${text} from 数据库 where 年份 in (2021,2022) group by 年份,月份`
const [results2, metadata2] = await sequelize.query(sql2)
//results2就是我们需要的结果了
扩展:通过以上语句就可以就可以获取我们所需要的表格了,后边我们对这个表格进行一下扩展,在获取销量的前提下,进一步获取每个企业的市场份额:
const sql3=`select 年份,月份,sum(销量) 合计 from 数据库 where 年份 in (2021,2022) group by 年份,月份`
const [results3, metadata3] = await sequelize.query(sql3)
//results3 是 每个月 全市场销量合计
const array3= results5.map(
obj=>obj.合计
) //将每个月市场销量转化为一个数组
results4.forEach(
(obj,index)=>{
for (var i=2;i<Object.keys(obj).length;i++){
obj[Object.keys(obj)[i]]= obj[Object.keys(obj)[i]]/array3[index]
}
}
) //通过forEach 语句以及 for循环 求出每个企业每个月的市场份额