生成可在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.
这是我正在尝试做的一个非常非常简化的例子(例如,真实场景涉及将'Everyone Else'分为三个分类行),但它说明了显示聚合的主要目标每个人的数据与其他人比较(独家)。伪代码会好的。我对SQL代码的第一次尝试非常迅速,我知道必须有一个更直接的方法。
任何提示赞赏。
答案 0 :(得分:1)
首先,我需要一些辅助变量来计算总数
/* 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
。
答案 1 :(得分: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
的第二部分肯定可以改进,但已经很晚了,我不能直接思考..)
答案 2 :(得分:0)
在SSRS中,在表格中添加一个额外的细节行。然后在聚合函数上使用Scope参数,并根据第一原则进行平均。
例如:
(Sum(Fields!Sales.Value, "table1") - Fields!Sales.Value)
/
(Sum(Fields!NumSales.Value, "table1") - Fields!NumSales.Value)
答案 3 :(得分: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