如何将我的枢轴列除以整行的总数?

时间:2014-04-30 21:03:45

标签: sql sql-server-2012 pivot common-table-expression

我有以下查询,我几乎(我认为)我需要得到它。但是,下图中的总和需要除以行中计数的总和,以百分比形式显示,而不是原始计数。

   WITH    cteServices ( [Cnt], OrgName, CatName )
              AS ( SELECT  DISTINCT
                            COUNT(DISTINCT [S].[ServiceId]) AS 'EBPServices' ,
                            [O].[OrganizationName] ,
                            cref.CSAPCategoryName
                   FROM     DVSdmPA.[DM].[Organizations] AS O
                            LEFT JOIN DVSdmPA.[DM].[Programs] AS P ON [O].[OrganizationID] = [P].[OrganizationId]
                            LEFT JOIN DVSdmPA.[DM].[Services] AS S ON [P].[ProgramId] = [S].[ProgramId]
                                                                  AND [S].[FiscalYear] IN (
                                                                  CAST('Jul  1 2012 12:00AM' AS DATETIME) )
                            INNER JOIN DVSdmPA.[MDM_ST].[CountySCALink] AS CSCAL ON [O].[OrganizationId] = [CSCAL].[OrganizationID]
                            INNER JOIN DVSdmPA.[MDM_ST].[SCAReference] AS SCAR ON [CSCAL].[CountyID] = [SCAR].[CountyID]
                            INNER JOIN DVSMDM.GIS.CountyBoundaries CB ON CSCAL.CountyID = CB.CountyId
                            INNER JOIN DVSdmPA.MDM.CSAPCategoryReference cref ON s.CSAPCategoryCode = cref.CSAPCategoryId
                   WHERE    [O].[OrganizationName] NOT IN ( 'National Guard',
                                                            'BDAP Problem Gambling Prevention Pilot',
                                                            'Clarion' )
                            AND s.CSAPCategoryCode IS NOT NULL
                   GROUP BY [O].[OrganizationName] ,
                            cref.CSAPCategoryName
                 )
        SELECT  OrgName ,
                ISNULL(Alternatives, 0) AS Alternatives ,
                ISNULL([Community-Based Process], 0) AS [Community-Based Process] ,
                ISNULL(Education, 0) AS Education ,
                ISNULL(Environmental, 0) AS Environmental ,
                ISNULL([Information Dissemination], 0) AS [Information Dissemination] ,
                ISNULL([Problem Identification and Referral], 0) AS [Problem Identification and Referral]
        FROM    ( SELECT    cnt ,
                            OrgName ,
                            CatName
                  FROM      cteServices
                ) src PIVOT ( SUM(cnt) FOR src.CatName IN ( Alternatives,
                                                            [Community-Based Process],
                                                            Education,
                                                            Environmental,
                                                            [Information Dissemination],
                                                            [Problem Identification and Referral] ) ) AS result
        ORDER BY orgname;

enter image description here

2 个答案:

答案 0 :(得分:1)

一个简单的解决方法就是将每一行除以总和,就像这样(丑陋,但它有效):

ISNULL(Alternatives, 0) / (ISNULL(Alternatives, 0) + ISNULL([Community-Based Process], 0) + ISNULL(Education, 0) + ISNULL(Environmental, 0) + ISNULL([Information Dissemination], 0) + ISNULL([Problem Identification and Referral], 0)) as AlternativesPercent

您还可以使用WHEREGROUP BY计算子查询中的总和 - 同样的想法,只是更清洁。

更重要的是,您应该考虑是否想要合并这样的数据。在您提供的图像中,当有人问“让我看看贝德福德的5环境”时会发生什么 - 您需要运行另一个查询。如果你更进一步提供百分比而不是名义数字,你会得到更多的问题,比如“什么是更大的,20%的阿勒格尼或60%的布莱尔?”。像Excel或任何商业智能程序这样的工具可以轻松处理原始数据,并且可以非常轻松地创建您在此处努力制作的相同数据透视表。在Excel中将一个百分比格式化为1个十进制的其他内容比在SQL Server中这样做要容易得多。 Excel和其他工具支持钻取...您可以点击贝德福德的5环境,他们将立即显示为列表。因此,您将获得两全其美 - 合并的数据透视表和原始数据。 SQL只需要额外的查询来获取基础数据行。

考虑所有选择。

答案 1 :(得分:0)

我的建议不是最有效的,但我认为应该有效:

将您的最终选择设置为cte(YourFinalSelectAsCte)

使用像

这样的选择添加另一个cte
,MyCTE as 
(
select 
    OrgName,
    (Alternatives+
    [Community-Based Process]
    Education+
    Environmental+
    [Information Dissemination]+
    [Problem Identification and Referral]) as SummedRow
    from YourFinalSelectAsCte
)

然后在OrgName上的YourFinalSelectAsCte上加入MyCTE,将每个条目除以SummedRow

我再次加入OrgName并不是最有效的,应该在之前的ctes'中重复使用ServiceId并将其用作连接。

希望我能正确理解你的问题。