2014-01-07 171 views
3

現在我在我的sql查詢中使用臨時表,但我想使用Partition By函數。使用OVER(PARTITION BY)而不是Group

我的臨時表的查詢如下:

drop table #Temp; 

create table #Temp 
(
    NAME varchar(50), 
    EMPID varchar(50), 
    SS MONEY, 
    PP MONEY 
); 

insert into #Temp 
select * From 
( 
    select 
    p1.NAME, 
    p1.EMPID, 
    case when p1.AmtPayer = 'SELF' then sum(p1.Salary) else 0 end as S, 
    case when p1.AmtPayer = 'MANAGER' then sum(p1.Salary) else 0 end as P 
    from Candidate p1 
    group by p1.Name, p1.EMPID, p1.AmtPayer 
) as P; 

select 
t.NAME, 
t.EMPID, 
sum(t.SS) as 'SELF PAID', 
sum(t.PP) as 'PARTY PAID' 
from #Temp t 
group by t.NAME, t.EMPID; 

我得到預期的結果很好,但我想用分區功能來執行此操作,我試過了,但結果是不準確的 -

select 
NAME, 
EMPID, 
sum(Salary) over (partition by AmtPayer) as Total 
from dbo.Candidate 

輸出是:

 
Vivek 0001 300.00 
Vivek 0001 300.00 
Vivek 0001 6200.00 
Vivek 0001 6200.00 
Vivek 0001 6200.00 

但我需要:

 
Vivek 0001 6200.00 300.00 
+0

請縮進代碼,以便它顯示了作爲代碼和格式,它有一定程度的理智......這真的很難閱讀。 –

+0

如果你想分組結果,你需要使用group by。窗口函數的全部目的不是**不「減少」結果集。 –

+0

[將多個子查詢中的多個結果合併爲一個逗號分隔值]的可能重複(http://stackoverflow.com/questions/111341/combine-multiple-results-in-a-subquery-into-a-single-逗號分隔值) –

回答

8

做的正是你想要的東西,試試這個:

select 
Name, EmpId, 
sum(case when AmtPayer = 'SELF' then Salary else 0 end) as [Self], 
sum(case when AmtPayer = 'MANAGER' then Salary else 0 end) as [Manager] 
from dbo.Candidate 
group by Name, EmpId; 

您可以使用聚合函數case語句,它使您能夠做很多瘋狂的事情:)

然而,正如我在對您的問題的評論中指出的那樣,這隻有在您預先知道固定數量的AmtPayer變體時纔有用。

詳細說明:partition by是明確設計的而不是以減少結果集。它仍然會返回每行一行,並且沒有什麼可以做的改變 - 如果你想減少結果集,你可以用group by來代替。結合所有複雜的東西,你可以使用聚合函數,這實際上是一個非常強大的工具 - 這適用於partition bygroup by。還請注意,partition by可能比group by慢得多。實際上,我發現使用分區來得到結果數(例如,count over (partition by NULL)或類似的東西)要比簡單地執行兩個查詢慢得多,一個只用於計數,另一個用於實際結果。

不要認爲你的方式更好,因爲它看起來更聰明 - 總是衡量。分析是你的朋友。像SQL Server系統做了很多的優化,嘗試所有的時間給你的看似愚蠢的查詢:)

0

我用下面的查詢出色的性能:

DROP TABLE #Temp 
CREATE TABLE #Temp(
NAME VARCHAR(50), 
EMPID VARCHAR(50), 
SS MONEY, 
PP MONEY 
) 
INSERT INTO #Temp 
Select * From(
SELECT DISTINCT 
    NAME,EMPID, 
    SUM(CASE WHEN AmtPayer='SELF' then Salary ELSE 0 end) OVER (PARTITION BY AmtPayer) AS SS , 
    SUM(CASE WHEN AmtPayer='MANAGER' THEN Salary ELSE 0 end) OVER (PARTITION BY AmtPayer) AS PP 
FROM dbo.Candidate 
)AS P 
SELECT DISTINCT t.NAME ,t.EMPID ,SUM(t.SS) OVER(PARTITION BY t.NAME,t.EMPID) AS 'SELF PAID', 
SUM(t.PP) OVER(PARTITION BY t.NAME,t.EMPID) AS 'PARTY PAID' FROM #Temp t 
--GROUP BY t.NAME ,t.EMPID 
相關問題