2009-12-21 67 views
3

什麼是最簡單的方法來生產,可以在SQL Server Reporting Services報表中使用的數據集,顯示如下:需要用SQL聚集查詢幫助

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代碼的速度非常快,我知道必須有更直接的方法。

任何提示讚賞。

+0

您是否有能力使用SSAS。它有一些設施,使得這很容易 – DrewM 2009-12-21 21:23:23

+1

獲取信息很容易,它的格式在你提供的佈局,這將是一個痛苦。通常,總計和計算僅顯示在結果集的末尾。 – 2009-12-21 21:29:36

+0

+1給Ponies的評論。 SQL不是格式化輸出的正確工具。 – 2009-12-21 21:31:51

回答

1

如果你不介意以後格式化,然後如果我們假設你有這樣的:

sales_model_02

首先,我將需要總計數一些輔助變量

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

然後我們在給定的p中爲每個人提取總數eriod(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 */ 

現在對於每個人vs所有其他人,但都在一行。

/* 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

+0

當所有的銷售人員被認爲屬於同一類別時,這很好。你將如何調整它以通過三級層次結構(人與分支,人與地區,人與國家)來提供綜合比較? – 2009-12-22 15:39:38

+0

規定該人在分支,地區,國家 - 'WHERE [Year] = 2009和[Region] ='North'',或WHERE [Year] = 2009 AND [Country] ='Canada'';基本上在分支,地區,國家過濾。 – 2009-12-22 16:29:00

+0

謝謝,達米爾。對,你會給我一個人需要的東西。我實際上正在考慮一次爲多人運行結果集。我不確定這個分組是多麼容易。任何想法? – 2009-12-22 17:23:38

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的第二部分,絕對可以得到改善,但它是晚,我想不清楚..)

0

在SSRS中,在表格中放置額外的細節行。然後在集合函數上使用Scope參數,並根據第一原則進行平均。

如:

(Sum(Fields!Sales.Value, "table1") - Fields!Sales.Value) 
/
(Sum(Fields!NumSales.Value, "table1") - Fields!NumSales.Value) 
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