SQL Server求解最近多少销售记录的销售额占比总销售额的指定比例

具体的问题描述我通过潇潇隐者的博文的截图来阐释:
在这里插入图片描述

注意:如果以上截取有所侵权,也请作者告知,再次感谢。

当看到这个问题的,我想到了是窗口函数提供的累积汇总有关的解决方案。

准备测试数据,有关的T-SQL代码如下:

IF OBJECT_ID(N'dbo.SalesData', N'U') IS NOT NULL
BEGIN
    DROP TABLE dbo.SalesData;
END
GO

CREATE TABLE dbo.SalesData
(
    Product_Name CHAR(32) NOT NULL, --商品名称
    Sale_Amount FLOAT NOT NULL   --销售金额
);
GO

INSERT INTO dbo.SalesData (Product_Name, Sale_Amount)
SELECT 'ProductNameA', 13000 UNION ALL
SELECT 'ProductNameA', 12000 UNION ALL
SELECT 'ProductNameA', 9000 UNION ALL
SELECT 'ProductNameB', 167000 UNION ALL
SELECT 'ProductNameB', 137000 UNION ALL
SELECT 'ProductNameB', 107000 UNION ALL
SELECT 'ProductNameC', 78000 UNION ALL
SELECT 'ProductNameC', 12000;
GO

执行以下的T-SQL代码:

SELECT Product_Name, Sale_Amount
FROM dbo.SalesData;
GO

得到的结果如下:
在这里插入图片描述
注意:以上测试数据也是来自潇潇隐者的博文,我再次基础上做了调整。

基于SQL Server 2005和以上的版本的解决方案的T-SQL代码如下:

-- SQL Server 2005 和以上版本 使用子查询的解决方案
SELECT *
FROM (
    SELECT T.Product_Name, T.Sale_Amount, T.rownum, T.Sale_TotalAmount, T.Sale_AccumulateAmount
        ,100.0 * T.Sale_AccumulateAmount / T.Sale_TotalAmount AS Sale_AccumulatePercent
    FROM (
        SELECT T.Product_Name, T.Sale_Amount, ROW_NUMBER() OVER (ORDER BY T.Sale_Amount DESC) AS rownum, T2.Sale_TotalAmount
            ,(SELECT SUM(Sale_Amount) FROM dbo.SalesData WHERE Sale_Amount >= T.Sale_Amount) AS Sale_AccumulateAmount
        FROM dbo.SalesData AS T
        CROSS APPLY (SELECT SUM(Sale_Amount) AS Sale_TotalAmount FROM dbo.SalesData) AS T2
    ) AS T
) AS T
WHERE T.Sale_AccumulatePercent <= 80;
GO

执行后的查询结果如下:
在这里插入图片描述

基于SQL Server 2012和以上的版本的解决方案的T-SQL代码如下:

-- SQL Server 2012 和以上 使用增强的窗口函数的解决方案
SELECT T.Product_Name, T.Sale_Amount, T.rownum, T.Sale_TotalAmount, T.Sale_AccumulateAmount, T.Sale_AccumulatePercent
FROM (
    SELECT T.Product_Name, T.Sale_Amount, T.rownum, T.Sale_TotalAmount, T.Sale_AccumulateAmount
    ,100.0 * T.Sale_AccumulateAmount / T.Sale_TotalAmount AS Sale_AccumulatePercent /*累计销售额在总销售中的百分比*/
    FROM (
        SELECT Product_Name, Sale_Amount, ROW_NUMBER() OVER (ORDER BY Sale_Amount DESC) AS rownum /*行号行数,具有不确定性,窗口排序字句列不唯一*/
        ,SUM(Sale_Amount) OVER () AS Sale_TotalAmount /*总销售额*/
        ,SUM(Sale_Amount) OVER (ORDER BY Sale_Amount DESC ROWS UNBOUNDED PRECEDING) AS Sale_AccumulateAmount /* 累计销售额,使用了SQL Server 2012窗口函数新增的窗口框架字句,也等同于 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW*/
        FROM dbo.SalesData
    ) AS T
) AS T
WHERE T.Sale_AccumulatePercent <= 90;
GO

执行后的查询结果如下:
在这里插入图片描述


SQL计算出百分比

clientslead_sources俩表。mysql数据库。

lead_sources表结构类似:
在这里插入图片描述
clients表中的lead_source_id是外键。现在要统计某时间段内client内每种lead_source所占百分比

select 
a.L_name, 
ROUND((a.L_sub_count*1.0/b.total_count*100),1) as perTotal,
a.L_sub_count,
b.total_count
from
(
SELECT LeadSource.name as L_name, count(*) as L_sub_count
FROM clients as Client,lead_sources as LeadSource
where 
    Client.lead_source_id = LeadSource.id 
    and LENGTH(Client.lead_source_id) > 0
    and Client.created_date BETWEEN '2012-09-01' AND '2012-11-01'
GROUP BY LeadSource.`name`
order by L_sub_count desc
)  a,
(
select count(*) as Total_count FROM clients as Client,lead_sources as LeadSource where     
    Client.lead_source_id = LeadSource.id 
    and LENGTH(Client.lead_source_id) > 0
    and Client.created_date BETWEEN '2012-09-01' AND '2012-11-01'
) b;

这个SQL有三个select,所以看成三部分,我的理解,后两个是构造虚表和字段。目的就是用于第一个select的查询。

结果类似:
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值