SQL - 按月计算客户总订单百分比

时间:2018-03-01 09:07:20

标签: sql sql-server

我在这个网站上练习SQL:https://www.w3schools.com/sql/trysqlserver.asp?filename=trysql_func_sqlserver_substring ,我正在尝试按客户ID计算每月订单总数的百分比。因此,例如,如果客户10在1月份有3个订单,并且1月份共有33个订单,那么1月份客户10的结果将是3/33 = 9.09%。我希望每一行都是客户ID,每个月都有一列。

基本上,我想转换它:

enter image description here

进入这个:

enter image description here

我可以按月获得总数,但是我无法获得百分比。

我正在使用此代码:

SELECT d.CustomerID,
       SUM(CASE WHEN Month = 01 THEN NumOrders ELSE 0 END) AS Jan,
       SUM(CASE WHEN Month = 02 THEN NumOrders ELSE 0 END) AS Feb,
       SUM(CASE WHEN Month = 03 THEN NumOrders ELSE 0 END) AS Mar,
       SUM(CASE WHEN Month = 04 THEN NumOrders ELSE 0 END) AS Apr,
       SUM(CASE WHEN Month = 05 THEN NumOrders ELSE 0 END) AS May,
       SUM(CASE WHEN Month = 06 THEN NumOrders ELSE 0 END) AS Jun,
       SUM(CASE WHEN Month = 07 THEN NumOrders ELSE 0 END) AS Jul,
       SUM(CASE WHEN Month = 08 THEN NumOrders ELSE 0 END) AS Aug,
       SUM(CASE WHEN Month = 09 THEN NumOrders ELSE 0 END) AS Sep,
       SUM(CASE WHEN Month = 10 THEN NumOrders ELSE 0 END) AS Oct,
       SUM(CASE WHEN Month = 11 THEN NumOrders ELSE 0 END) AS Nov,
       SUM(CASE WHEN Month = 12 THEN NumOrders ELSE 0 END) AS [Dec],
       SUM(NumOrders) AS Total
       FROM(
       SELECT CustomerID,
               DATEPART(mm,OrderDate) AS Month,
               COUNT(OrderID) AS NumOrders
          FROM Orders
          GROUP BY CustomerID,
                  DATEPART(mm,OrderDate)
         ) d
GROUP BY d.CustomerID
WITH ROLLUP

我已经尝试过使用这样的代码来计算百分比,但是我没有让它成功。

SUM(CASE WHEN Month = 01 THEN NumOrders ELSE 0 END) / CAST( SUM(NumOrders) OVER (PARTITION BY Month) AS FLOAT) AS JanPct,

这在Excel中非常基础,看起来它也应该在SQL中,所以我觉得我错过了一些明显的东西。

3 个答案:

答案 0 :(得分:0)

试试这个

    Create table #tmp (CustId INT, Jan int, Feb Int, March int)

    insert into #tmp VALUES
    (10,4,3,5),
    (11,3,1,7),
    (12,6,2,6),
    (13,5,4,4);

    Select * from #tmp


    select CustId,
           CEILING(CAST(Jan As FLOAT)/CAST(SUM(Jan) OVER() AS FLOAT)*100) As Jan,
           CEILING(CAST(Feb As FLOAT)/CAST(SUM(Feb) OVER() AS FLOAT)*100) As Feb,
           CEILING(CAST(March As FLOAT)/CAST(SUM(March) OVER() AS FLOAT)*100) As March
     from #tmp


    drop table #tmp

如果您想要%符号,请转换为varchar并附加%

例如:

  CONVERT(VARCHAR(5),CEILING(CAST(Jan As FLOAT)/CAST(SUM(Jan) OVER() AS FLOAT)*100))+'%'

答案 1 :(得分:0)

我无法使用PIVOT进行汇总工作,所以这是一个很长的解决方案。

DECLARE @t table(OrderId INT identity(1,1), OrderDate date, CustomerID INT)

INSERT @t values('2017-01-01', 1),('2017-01-01', 1),('2017-02-01', 1),('2017-01-01', 2)

;WITH CTE as
(
  SELECT DISTINCT
    CAST(ROUND(count(*) over(partition by CustomerID, Month(OrderDate))*100./ count(*)
      over(partition by month(OrderDate)), 0) as INT) Pct,
    Month(OrderDate) Mon,
  CustomerID
FROM @t
)
SELECT
  CustomerID,
  SUM(CASE WHEN Mon = 1 THEN Pct ELSE 0 END) AS Jan,
  SUM(CASE WHEN Mon = 2 THEN Pct ELSE 0 END) AS Feb,
  SUM(CASE WHEN Mon = 3 THEN Pct ELSE 0 END) AS Mar,
  SUM(CASE WHEN Mon = 4 THEN Pct ELSE 0 END) AS Apr,
  SUM(CASE WHEN Mon = 5 THEN Pct ELSE 0 END) AS May,
  SUM(CASE WHEN Mon = 6 THEN Pct ELSE 0 END) AS Jun,
  SUM(CASE WHEN Mon = 7 THEN Pct ELSE 0 END) AS Jul,
  SUM(CASE WHEN Mon = 8 THEN Pct ELSE 0 END) AS Aug,
  SUM(CASE WHEN Mon = 9 THEN Pct ELSE 0 END) AS Sep,
  SUM(CASE WHEN Mon = 10 THEN Pct ELSE 0 END) AS Oct,
  SUM(CASE WHEN Mon = 11 THEN Pct ELSE 0 END) AS Nov,
  SUM(CASE WHEN Mon = 12 THEN Pct ELSE 0 END) AS [Dec]
FROM CTE
GROUP BY ROLLUP (CustomerID)

答案 2 :(得分:0)

只需使用以下代码,而不是在以下子查询中选择COUNT(OrderID) AS NumOrders

CONVERT(numeric(10,2), count(Orderid) * 100.0/ (select count(Orderid) from [Orders]))  as NumOrders