2010-05-08 128 views
3

我有一個postgresql表,其中包含倉庫間不同項目(模型)的移動。使用SQL進行分組時計算行之間的差異

例如,以下記錄意味着,5個單位的模型1的已發送形式倉庫1至2:

source target model units 
------ ------ ----- ----- 
    1  2  1  5 

我試圖建立一個SQL查詢來獲得發送和接收單元之間的差,按模型分組。再一個例子:

source target model units 
------ ------ ----- ----- 
    1  2  1  5 -- 5 sent from 1 to 2 
    1  2  2  1 
    2  1  1  2 -- 2 sent from 2 to 1 
    2  1  1  1 -- 1 more sent from 2 to 1 

結果應該是:

source target model diff 
------ ------ ----- ---- 
    1  2  1 2 -- 5 sent minus 3 received 
    1  2  2 1 

我不知道這是否可能與一個SQL查詢

下面是表創建腳本和一些數據,以防萬一有人想嘗試一下:

CREATE TEMP TABLE movements 
(
    source INTEGER, 
    target INTEGER, 
    model INTEGER, 
    units INTEGER 
); 

insert into movements values (1,2,1,5); 
insert into movements values (1,2,2,1); 
insert into movements values (2,1,1,2); 
insert into movements values (2,1,1,1); 

回答

1

這是做你所需要的嗎?我沒有一個Oracle數據庫再次進行測試,所以我希望在分組表達式規則是相同的MS SQL Server

SELECT  
CASE WHEN source < target THEN source ELSE target END AS source, 
CASE WHEN source < target THEN target ELSE source END AS target, 
SUM(CASE WHEN source < target THEN units ELSE -units END) AS Diff, 
    model 
FROM movements 
GROUP BY 
CASE WHEN source < target THEN source ELSE target END, 
CASE WHEN source < target THEN target ELSE source END, 
    model 
4

您可以用兩個子查詢該款項在各個方向的運動,然後工會和sum做到這一點這兩個子查詢的結果如下:

SELECT source, target, model, SUM(units) 
FROM (
    SELECT source, target, model, SUM(units) AS units 
    FROM movements 
    WHERE source < target 
    GROUP BY source, target, model 
    UNION ALL 
    SELECT target, source, model, SUM(-units) AS units 
    FROM movements 
    WHERE source > target 
    GROUP BY source, target, model 
) T1 
GROUP BY source, target, model 
+0

偉大的答案!非常清楚! – msemelman 2010-05-08 19:14:41

+0

謝謝,讓我試試看。你的查詢與@Martin Smith提供的查詢相比,如何避免使用「UNION ALL」(使用一些CASE子句)? – 2010-05-08 19:47:40

+1

@Guido:他的答案只掃描一次,我的掃描兩次。你有多少行?性能是一個問題嗎?我會聲稱我的建議更清楚/可讀,但那是我自己的觀點,並且是主觀的。 – 2010-05-08 19:54:35