计算分组内的百分比

时间:2017-05-27 02:37:12

标签: sql-server tsql common-table-expression

我正在尝试从我的桌子计算男性和女性的百分比;到目前为止,我已计算出来自我餐桌的女性,男性和未公开的总人数。但后来我想从这些总数中计算女性和男性的百分比。

我的初步查询如下:

SELECT   [description] AS [Gender] ,
     COUNT(C.id) AS [GenderCount]
FROM     dbo.Customers AS [C]
     INNER JOIN dbo.GenderTypes AS [GT] ON C.genderTypeID = GT.id
WHERE    C.customerStatusTypeID = 'O'
GROUP BY GT.[description]

结果:

Gender      GenderCount
Female      60620
Male        394165
Undisclosed 630007

我试图在CTE中包装查询以使用case语句计算百分比,但我显然遗漏了一些东西,因为女性,男性和未公开都是100%。

;WITH Gender (Gender, GenderCount)
AS 
(
SELECT   [description] AS [Gender] ,
     COUNT(C.id) AS [GenderCount]
FROM     dbo.Customers AS [C]
     INNER JOIN dbo.GenderTypes AS [GT] ON C.genderTypeID = GT.id
WHERE    C.customerStatusTypeID = 'O'
GROUP BY GT.[description] )
SELECT Gender.Gender, Gender.GenderCount,
CASE WHEN
Gender.Gender = 'Female' THEN Gender.GenderCount / SUM(Gender.GenderCount) * 100
WHEN Gender.Gender = 'Male' THEN Gender.GenderCount / SUM(Gender.GenderCount) * 100
ELSE Gender.GenderCount / SUM(Gender.GenderCount) * 100
END AS [%Gender]
FROM Gender
GROUP BY Gender.Gender, Gender.GenderCount;

结果如下:

Gender       GenderCount    %Gender
Female       60620          100
Male         394165         100
Undisclosed  630007         100

如果我的数学/ TSQL是正确的,结果应该如下:

Female: 5.59%
Male: 36.34%
Undisclosed: 58.08%

任何人都可以帮我解决我所缺少的问题,以获得正确的结果吗?

2 个答案:

答案 0 :(得分:1)

您可以使用以下查询

DECLARE @SampleData AS TABLE
(
    Gender varchar(20),
    GenderCount int
)

INSERT INTO @SampleData
VALUES
('Female', 60620),
('Male', 394165),
('Undisclosed', 630007)

SELECT  *, 
       CAST(CAST(sd.GenderCount AS decimal)/sum(sd.GenderCount) over() *100 as decimal(10,2)) AS [%Gender] AS [%Gender]
FROM @SampleData sd

返回

Gender  GenderCount %Gender
Female  60620   5.59
Male    394165  36.34
Undisclosed 630007  58.08

您的查询可以像这样编写

;WITH temp as (
SELECT   [description] AS [Gender] ,
         COUNT(C.id) AS [GenderCount]
FROM     dbo.Customers AS [C]
     INNER JOIN dbo.GenderTypes AS [GT] ON C.genderTypeID = GT.id
WHERE    C.customerStatusTypeID = 'O'
GROUP BY GT.[description]
)
SELECT  *, 
        CAST(CAST(t.GenderCount AS decimal)/sum(t.GenderCount) over() *100 as decimal(10,2)) AS [%Gender]
FROM temp t

答案 1 :(得分:1)

您应该可以在不需要CTE的情况下执行此操作:

SELECT   SUM(CASE WHEN GT.Gender = 'Female' THEN 1 ELSE 0 END) * 100.00 / count(*) as FemalePercent,
         SUM(CASE WHEN GT.Gender = 'Male'   THEN 1 ELSE 0 END) * 100.00 / count(*) as MalePercent,
         SUM(CASE WHEN GT.Gender <> 'Male' AND GT.Gender <> 'Female'  THEN 1 ELSE 0 END) * 100.00 / count(*) as UndisclosedPercent,
FROM     dbo.Customers AS [C]
         INNER JOIN dbo.GenderTypes AS [GT] ON C.genderTypeID = GT.id
WHERE    C.customerStatusTypeID = 'O'

这将为您提供单行,其中3个百分比位于不同的列中。

如果您需要表格格式的结果,原始查询可以加入另一个提供记录总数的查询:

SELECT   GC.Gender,
         GC.GenderCount,
         GC.GenderCount * 100.00 / T.Total as Percentage
FROM
(
    SELECT   [description] AS [Gender] ,
             COUNT(C.id) AS [GenderCount]
    FROM     dbo.Customers AS [C]
             INNER JOIN dbo.GenderTypes AS [GT] ON C.genderTypeID = GT.id
    WHERE    C.customerStatusTypeID = 'O'
    GROUP BY GT.[description]
) GC
cross join
(
    SELECT Count(*) as Total
    FROM dbo.Customers C
    WHERE C.customerStatusTypeID = 'O'
) T