SQL查询:获取每行的调整值

时间:2014-11-14 18:33:16

标签: sql postgresql

我在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

我可以得到总和或调整后的值,但不能同时得到两者。

2 个答案:

答案 0 :(得分: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 ()window functions的语法。
  • 我还添加了[CAST()][3]以汇总值。

答案 1 :(得分: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