我在这个网站上练习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,每个月都有一列。
基本上,我想转换它:
进入这个:
我可以按月获得总数,但是我无法获得百分比。
我正在使用此代码:
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中,所以我觉得我错过了一些明显的东西。
答案 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