2014-11-14 74 views
1

我在SQL表中有幾列,我想計算表中每一行的結果。我的數據看起來是這樣的:SQL查詢:獲取每行的調整值

data 
name  value adjustor1 adjustor2 
Comp1 20  0.05  0.08 
Comp2 80  -0.07  0.065 

的每一行的調整值的計算公式爲:

adjusted_value = value*(1 + adjustor1)*(1 + adjustor2)*(100/sum(value)) 

所以調整後的輸出應該是:

data 
name  adjusted_value 
Comp1 22.25 
Comp2 77.75 

原始值總和到100,調整後的值也應該總和爲100.我試過的東西如:

SELECT adjusted*(100/sum(adjusted)) 
FROM (
     SELECT value*(1+adjustor1)*(1+adjustor2) as adjusted 
     FROM data 
) as result 

它給我的錯誤:ERROR: column "result.adjusted" must appear in the GROUP BY clause or be used in an aggregate function

但如果我只是做:

SELECT sum(adjusted) 
FROM (
     SELECT value*(1+adjustor1)*(1+adjustor2) as adjusted 
     FROM data 
) as result 

OR

SELECT adjusted 
FROM (
     SELECT value*(1+adjustor1)*(1+adjustor2) as adjusted 
     FROM data 
) as result 

我能得到任何總和或調整值,但不能同時。

回答

1

列名value是不是一個好的選擇,這是一個保留字。我將其改爲val

這是你需要查詢:

WITH data(name,val,adjustor1,adjustor2) AS (
    VALUES 
    ('Comp1'::text,20,0.05,0.08), 
    ('Comp2',80,-0.07,0.065) 
) 
SELECT name,val,adjustor1,adjustor2, 
     CAST(val*(1+adjustor1)*(1+adjustor2)*(100/sum(
     val*(1+adjustor1)*(1+adjustor2) 
     ) OVER()) AS numeric(10,3)) adjusted_value 
    FROM data; 

我必須承認,這是一個有點笨拙,子查詢可以更容易地理解(SQL Fiddle):

WITH data(name,val,adjustor1,adjustor2) AS (
    VALUES 
    ('Comp1'::text,20,0.05,0.08), 
    ('Comp2',80,-0.07,0.065) 
) 
SELECT name, CAST(adj*(100/sum(adj) OVER()) AS numeric(8,3)) adjusted_value 
    FROM (
    SELECT name,val,adjustor1,adjustor2, 
      val*(1+adjustor1)*(1+adjustor2) adj 
     FROM data) s; 

一些注意事項:

  • 原始sum(adj)被替換爲sum(adj) OVER(),這是0123的語法。
  • 我也加了[CAST()][3]爲了收集數值。
+0

我一直在玩OVER(?)語法一段時間,但我無法弄清楚把它放在哪裏。這看起來很完美,消除了重複子查詢或交叉連接的需要。 – 2014-11-14 19:44:04

0

你可以得到一個子查詢的SUM,然後你可以做CROSS JOIN達到你想要什麼

SELECT name, 
     value*(1+adjustor1)*(1+adjustor2)*(100/T.adjSum) as adjusted_value 
FROM data 
CROSS JOIN 
(SELECT SUM(value*(1+adjustor1)*(1+adjustor2)) as adjSum 
FROM data) T