如何根据汇总列总销售额计算收入百分比?

时间:2014-10-13 21:23:44

标签: tsql sql-server-2012 adventureworks

我正在尝试添加一个计算总收入百分比的列,但我遇到了以下错误:

  

错误:消息207,级别16,状态1,行14无效的列名称   'Customerkey'。

在该行中,我正在尝试加入表1和表3,但即使T.Customerkey表中存在customerkey,MS SQL Server也无法识别dbo.FactInternetSales。 此外,当我在Group By子句中添加T.Grand_Tot_Rev时,每行返回0.04。我知道这是错误的,因为我不希望T.Grand_Tot_Rev成为聚合的一部分,因为它应该对每个记录保持不变。我怎样才能实现我想要的?先感谢您。顺便说一下,我正在使用AdventureWorksDW2012数据库。

SELECT fs.CustomerKey , 
       M.Total_sales , 
       M.Total_cost , 
       M.Total_sales - M.Total_cost AS Total_Margin , 
       T.Grand_Tot_Rev( M.Total_sales / T.Grand_Tot_Rev ) * 100 AS Prct_Total_Revenue
  FROM dbo.FactInternetSales fs , -- Table 1 --

( 
  SELECT customerkey , 
         SUM( SalesAmount )AS Total_Sales , 
         SUM( TotalProductCost )Total_cost
    FROM dbo.FactInternetSales
    GROUP BY customerkey 
) M , --Table 2 --

( 
  SELECT SUM( SalesAmount )AS Grand_Tot_Rev
    FROM dbo.FactInternetSales 
) T --Table 3 --

  WHERE fs.CustomerKey =  M.CustomerKey -- Join 1 --     
    AND M.CustomerKey = T.Customerkey   -- Join 2 -- 
  GROUP BY fs.CustomerKey , 
           M.Total_sales , 
           M.Total_cost , 
           T.Grand_Tot_Rev
  ORDER BY 2 DESC;

1 个答案:

答案 0 :(得分:1)

如果您希望T.Grand_Tot_Rev作为所有行的常量,请尝试删除第二个连接AND M.CustomerKey = T.Customerkey -- Join 2 --,以便查询如下所示:

SELECT fs.CustomerKey , 
       M.Total_sales , 
       M.Total_cost , 
       M.Total_sales - M.Total_cost AS Total_Margin , 
       T.Grand_Tot_Rev,
      ( M.Total_sales / T.Grand_Tot_Rev ) * 100 AS Prct_Total_Revenue
  FROM dbo.FactInternetSales fs , -- Table 1 --

( 
  SELECT customerkey , 
         SUM( SalesAmount )AS Total_Sales , 
         SUM( TotalProductCost )Total_cost
    FROM dbo.FactInternetSales
    GROUP BY customerkey 
) M , --Table 2 --

( 
  SELECT SUM( SalesAmount )AS Grand_Tot_Rev
    FROM dbo.FactInternetSales
) T --Table 3 --

  WHERE fs.CustomerKey =  M.CustomerKey -- Join 1 --     
    --AND M.CustomerKey = T.Customerkey    -- Join 2 -- 
  GROUP BY fs.CustomerKey , 
           M.Total_sales , 
           M.Total_cost , 
           T.Grand_Tot_Rev
  ORDER BY 2 DESC;

编写相同查询的另一种方法是更紧凑,性能稍好一些:

;WITH 
    T AS (
        SELECT SUM(SalesAmount) AS Grand_Tot_Rev  
        FROM dbo.FactInternetSales
    ),
    M AS (
       SELECT customerkey , 
        SUM(SalesAmount) AS Total_Sales , 
        SUM(TotalProductCost) AS Total_cost
       FROM dbo.FactInternetSales
       GROUP BY CustomerKey
)

SELECT 
    customerkey , 
    Total_Sales , 
    Total_cost,
    Total_Sales - Total_cost AS Total_Margin , 
    Grand_Tot_Rev,
    Total_Sales / Grand_Tot_Rev * 100 AS Prct_Total_Revenue   
FROM M, T
ORDER BY 2 DESC;

要查看非常小的值,您可以强制转换为更广泛的数据类型:

;WITH 
    T AS (
        SELECT CAST(SUM(SalesAmount) AS decimal) AS Grand_Tot_Rev  
        FROM dbo.FactInternetSales
    ),
    M AS (
       SELECT customerkey , 
        CAST(SUM(SalesAmount) AS decimal(15,10)) AS Total_Sales , 
        CAST(SUM(TotalProductCost) AS decimal(15,10)) AS Total_cost
       FROM dbo.FactInternetSales
       GROUP BY CustomerKey
)

SELECT 
    customerkey , 
    Total_Sales , 
    Total_cost,
    Total_Sales - Total_cost AS Total_Margin , 
    Grand_Tot_Rev,
    Total_Sales / Grand_Tot_Rev * 100 AS Prct_Total_Revenue   
FROM M, T
ORDER BY 2 DESC;