【问题标题】:Calculate percentage while select - T-SQL选择时计算百分比 - T-SQL
【发布时间】:2022-01-26 21:50:54
【问题描述】:

我有一个存储过程:

ALTER PROCEDURE GetReportData
AS
BEGIN
    SELECT 
        LOC.SubCompanyNameVN,
        LOC.BranchName,
        COUNT(LOC.BranchCode) as Total,

        ----------- Not Processed Yet
        -- Count
        (SELECT COUNT(WS.ID)
            FROM DBO.WorkingSession AS WS
            JOIN DBO.Location AS LO ON WS.LocationID = LO.LocationID AND WS.BranchCode = LO.BranchCode
            WHERE WS.Status = 5 OR WS.Status = 6 AND LO.BranchCode = LOC.BranchCode) AS CountNotProcessedYet,
        ------------

        ----------- Processing
        -- Count
        (SELECT COUNT(WS.ID)
            FROM DBO.WorkingSession AS WS
            JOIN DBO.Location AS LO ON WS.LocationID = LO.LocationID AND WS.BranchCode = LO.BranchCode
            WHERE WS.Status = 3 AND LO.BranchName = LOC.BranchName) AS CountProcessing,
        ------------
    FROM DBO.WorkingSession AS SS
    JOIN DBO.Location AS LOC ON SS.LocationID = LOC.LocationID AND SS.BranchCode = LOC.BranchCode
    JOIN DBO.Status AS ST ON SS.Status = ST.ID
    GROUP BY LOC.SubCompanyNameVN, LOC.BranchName, LOC.BranchCode
    ORDER BY LOC.SubCompanyNameVN
END

结果:

SubCompanyNameVN BranchName Total CountNotProcessedYet CountProcessing
Vùng 1 HNI_01 5 3 2
Vùng 1 HNI_02 15 5 10
Vùng 1 HNI_07 12 6 6

但我的预期结果是:

SubCompanyNameVN BranchName Total CountNotProcessedYet percentNotProcessedYet CountProcessing percentProcessing
Vùng 1 HNI_01 5 3 60% 2 40%
Vùng 1 HNI_02 15 5 33.33% 10 66.67%
Vùng 1 HNI_07 12 6 50% 6 50%

所以我像这样更新我的存储过程:

ALTER PROCEDURE GetReportData
AS
BEGIN
    SELECT 
        LOC.SubCompanyNameVN,
        LOC.BranchName,
        COUNT(LOC.BranchCode) as Total,

        ----------- Not Processed Yet
        -- Count
        (SELECT COUNT(WS.ID)
            FROM DBO.WorkingSession AS WS
            JOIN DBO.Location AS LO ON WS.LocationID = LO.LocationID AND WS.BranchCode = LO.BranchCode
            WHERE WS.Status = 5 OR WS.Status = 6 AND LO.BranchCode = LOC.BranchCode) AS CountNotProcessedYet,
         --- Percent
        ROUND((CountNotProcessedYet/Total)*100,2)
        ------------

        ----------- Processing
        -- Count
        (SELECT COUNT(WS.ID)
            FROM DBO.WorkingSession AS WS
            JOIN DBO.Location AS LO ON WS.LocationID = LO.LocationID AND WS.BranchCode = LO.BranchCode
            WHERE WS.Status = 3 AND LO.BranchName = LOC.BranchName) AS CountProcessing,
        --- Percent
        ROUND((CountProcessing/Total)*100,2)
        ------------
    FROM DBO.WorkingSession AS SS
    JOIN DBO.Location AS LOC ON SS.LocationID = LOC.LocationID AND SS.BranchCode = LOC.BranchCode
    JOIN DBO.Status AS ST ON SS.Status = ST.ID
    GROUP BY LOC.SubCompanyNameVN, LOC.BranchName, LOC.BranchCode
    ORDER BY LOC.SubCompanyNameVN
END

错误:

有什么方法可以计算百分比吗?

【问题讨论】:

    标签: sql sql-server tsql stored-procedures percentage


    【解决方案1】:

    首先在您收到的错误消息上,您不能像在同一级别上那样引用列别名。

    CountProcessing/Total
    

    您可以使用CTE 或派生查询来计算TotalCountProcessing,然后使用列别名在外部查询上计算Percent

    您可以使用CASE 表达式而不是子查询来简化您的查询

    SELECT
        LOC.SubCompanyNameVN,
        LOC.BranchName,
        COUNT(LOC.BranchCode) as [Total],
        SUM (CASE WHEN SS.Status IN (5,6) THEN 1 ELSE 0 END) as [CountNotProcessedYet],
        SUM (CASE WHEN SS.Status IN (3)   THEN 1 ELSE 0 END) as [CountProcessing],
        ROUND (SUM (CASE WHEN SS.Status IN (3)   THEN 1 ELSE 0 END) * 100.0 / COUNT(LOC.BranchCode), 2) as [Percent]
    FROM DBO.WorkingSession AS SS
    JOIN DBO.Location AS LOC ON SS.LocationID = LOC.LocationID AND SS.BranchCode = LOC.BranchCode
    JOIN DBO.Status AS ST ON SS.Status = ST.ID
    GROUP BY LOC.SubCompanyNameVN, LOC.BranchName
    ORDER BY LOC.SubCompanyNameVN
    

    【讨论】:

      【解决方案2】:

      您不能在流程的一个步骤中同时为列命名并为计算列使用相同的名称。如下所示更改您的查询

      ALTER PROCEDURE GetReportData
      AS
      BEGIN
        SELECT
          SubCompanyNameVN,
          BranchName,
          Total,
          CountNotProcessedYet,
          ROUND((CountNotProcessedYet/Total)*100,2),
          CountProcessing,
          ROUND((CountProcessing/Total)*100,2)
        FROM
          (SELECT 
              LOC.SubCompanyNameVN,
              LOC.BranchName,
              COUNT(LOC.BranchCode) as Total,
      
              ----------- Not Processed Yet
              -- Count
              (SELECT COUNT(WS.ID)
                  FROM DBO.WorkingSession AS WS
                  JOIN DBO.Location AS LO ON WS.LocationID = LO.LocationID AND WS.BranchCode = LO.BranchCode
                  WHERE WS.Status = 5 OR WS.Status = 6 AND LO.BranchCode = LOC.BranchCode) AS CountNotProcessedYet,
              ----------- Processing
              -- Count
              (SELECT COUNT(WS.ID)
                  FROM DBO.WorkingSession AS WS
                  JOIN DBO.Location AS LO ON WS.LocationID = LO.LocationID AND WS.BranchCode = LO.BranchCode
                  WHERE WS.Status = 3 AND LO.BranchName = LOC.BranchName) AS CountProcessing,
             
          FROM DBO.WorkingSession AS SS
          JOIN DBO.Location AS LOC ON SS.LocationID = LOC.LocationID AND SS.BranchCode = LOC.BranchCode
          JOIN DBO.Status AS ST ON SS.Status = ST.ID
          GROUP BY LOC.SubCompanyNameVN, LOC.BranchName, LOC.BranchCode) T
        ORDER BY LOC.SubCompanyNameVN
      END
      

      【讨论】:

        【解决方案3】:

        可能是这样

            SELECT 
                LOC.SubCompanyNameVN,
                LOC.BranchName,
                COUNT(SS.ID) as Total,
                COUNT(CASE WHEN SS.Status IN (5, 6)
                      THEN SS.ID END) AS CountNotProcessedYet, 
                ROUND((COUNT(CASE WHEN SS.Status IN (5, 6)
                      THEN SS.ID END)/COUNT(SS.ID))*100,2) AS PercentNotProcessedYet, 
                COUNT(CASE WHEN SS.Status = 3
                      THEN SS.ID END) AS CountProcessing, 
                ROUND((COUNT(CASE WHEN SS.Status = 3
                      THEN SS.ID END)/COUNT(SS.ID))*100,2) AS PercentProcessing
            FROM DBO.WorkingSession AS SS
            JOIN DBO.Location AS LOC ON SS.LocationID = LOC.LocationID AND SS.BranchCode = LOC.BranchCode
            JOIN DBO.Status AS ST ON SS.Status = ST.ID
            GROUP BY LOC.SubCompanyNameVN, LOC.BranchName, LOC.BranchCode
            ORDER BY LOC.SubCompanyNameVN
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-10-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-02-01
          • 2012-05-08
          • 1970-01-01
          • 2021-12-17
          相关资源
          最近更新 更多