3

生成可用于 SQL Server Reporting Services 报告以显示以下内容的数据集的最直接方法是什么:

SalesPerson        # Sales        # Gross        Profit
John Doe               100       $140,000       $25,000
Everyone Else (Avg.)  1200     $2,000,000      $250,000


Jane Smith              80       $100,000       $15,000
Everyone Else (Avg.)  1220     $2,040,000      $260,000


...and so on.

这是我正在尝试做的一个非常非常简化的示例(例如,真实场景涉及将“其他所有人”分成三个分类行),但它说明了显示每个类别的汇总数据的主要目标与其他人进行比较的个人(排他性的)。伪代码就好了。我对 SQL 代码的第一次尝试很快就变得很纠结,我知道一定有更直接的方法。

任何提示表示赞赏。

4

4 回答 4

1

如果您以后不介意格式化,那么如果我们假设您有类似的内容:

sales_model_02

首先,我需要一些辅助变量来计算总计数

/* Few helper variables*/
DECLARE @TotalQuantity int
       ,@TotalAmount decimal(19, 4)
       ,@TotalProfit decimal(19, 4)
       ,@EveryoneElse int

然后我们获取给定时间段内每个人的总数(YEAR = 2009)

/* Fetch totals in the period*/
SELECT  @TotalQuantity = sum(SalesQuantity)
       ,@TotalAmount = sum(SalesAmount)
       ,@TotalProfit = sum(Profit)
       ,@EveryoneElse = count(DISTINCT SalesPersonKey) - 1
FROM   factSales AS s
       JOIN dimDate AS d ON s.DateKey = d.DateKey
WHERE   [Year] = 2009

/* Now we have totals for everyone in the period */

现在对于每个人与其他所有人,但都排成一排。

/* Totals for each sales person vs everyone else Average */
SELECT  FullName
       ,SUM(SalesQuantity) AS [PersonSalesCount]
       ,SUM(SalesAmount) AS [PersonSalesAmount]
       ,SUM(Profit) AS [PersonSalesProfit]
       ,( @TotalQuantity - SUM(SalesQuantity) ) / @EveryoneElse AS [EveryoneElseAvgSalesCount]
       ,( @TotalAmount - SUM(SalesAmount) ) / @EveryoneElse AS [EveryoneElseAvgSalesAmount]
       ,( @TotalProfit - SUM(Profit) ) / @EveryoneElse AS [EveryoneElseAvgSalesProfit]
FROM    factSales AS s
        JOIN dimDate AS d ON s.DateKey = d.DateKey
        RIGHT JOIN dimSalesPerson AS p ON p.SalesPersonKey = s.SalesPersonKey
WHERE   [Year] = 2009
GROUP BY FullName

现在,您可以将所有这些打包在一个带有日期间隔参数的存储过程中。可能仍需要调整销售人员的数量,以确定哪些人在特定时期内是活跃的,以及如何计算那些没有销售任何东西的人。有了这个,EveryoneElse意味着销售东西的销售人员数量-1;因此,如果您有 10 个销售人员,而只有 5 个销售了某样东西,那么EveryoneElse = 4.

于 2009-12-21T23:56:46.703 回答
0

几乎可以肯定不是非常高效,但声明性清晰:

declare @i int = 0
declare @j int = 1

select * from
(
select (@i = @i + 2) as order_col, SalesPerson, sales, gross, profit
from myTable order by SalesPerson

union all

select (@j = @j + 2) as order_col, 'Everybody else'
, (select sum(sales) from myTable i where i.SalesPerson <> o.Salesperson)
, (select sum(gross) from myTable i where i.SalesPerson <> o.Salesperson)
, (select sum(profit) from myTable i where i.SalesPerson <> o.Salesperson)
from myTable o
order by SalesPerson
) x order by order_col

(第二部分UNION肯定可以改进,但是来晚了,想不通..)

于 2009-12-21T21:36:01.280 回答
0

在 SSRS 中,在表格中添加一个额外的详细信息行。然后在聚合函数上使用 Scope 参数,并根据第一原则进行平均。

例如:

(Sum(Fields!Sales.Value, "table1") - Fields!Sales.Value) 
/
(Sum(Fields!NumSales.Value, "table1") - Fields!NumSales.Value)
于 2009-12-21T21:48:39.897 回答
0

我在这里做了一些假设,但如果你有这样的桌子

If object_id('Sales') is not null 
  Drop table Sales

CREATE TABLE [dbo].[Sales]
(
 [Salesperson] [nvarchar](50) NULL,
 [Sales] [int] NULL,
 [Gross] [money] NULL,
 [Profit] [money] NULL,
)

像这样填充数据

Insert into Sales values ('John Doe', 100, 200.00, 100.00)
Insert into Sales values ('John Doe', 125, 300.00, 100.00)
Insert into Sales values ('Jane Smith', 100, 200.00, 100.00)
Insert into Sales values ('Jane Smith', 125, 1.00, 0.50)
Insert into Sales values ('Joel Spolsky', 100, 2.00, 1.00)
Insert into Sales values ('Joel Spolsky', 125, 3.00, 1.00)

然后像这样的存储过程可能会给你你正在寻找的东西

If object_id('usp_SalesReport') is not null 
Drop procedure usp_SalesReport

Go


Create Procedure usp_SalesReport
as
Declare @results as table
(
 SalesPerson nvarchar(50),
 Sales int,
 Gross money,
 Profit money
)

Declare  @SalesPerson nvarchar(50)
Declare SalesSums CURSOR FOR

Select  distinct SalesPerson from Sales

Open SalesSums

Fetch SalesSums INTO @SalesPerson

While @@Fetch_Status = 0

Begin
 Insert into @results Select Sales.Salesperson, sum(sales), sum(Gross), sum(profit) from Sales group by Sales.Salesperson having Sales.Salesperson = @SalesPerson
 Insert into @results Select 'EveryoneElse', avg(sales), avg(Gross), avg(profit) from Sales where Salesperson <> @SalesPerson

Fetch SalesSums INTO @SalesPerson          
End
Select * from @results
Close SalesSums
Deallocate SalesSums
Return
于 2009-12-22T16:20:29.710 回答