2013-08-17 79 views
0

我想查询哪里我计算两列之间的差异。喜欢的东西:在别名上使用聚合函数?

SELECT a, 
     b, 
     a - b as "diff" 
    FROM ... 

现在我想计算“差异”一栏的使用内置的STDDEV聚合函数PostgreSQL中STDDEV。我怎样才能做到这一点?

谢谢。

编辑:

的实际查询是这样的:

SELECT tr.date_start, 
     tr.date_end,  
     (((CASE when(tourney_summary.val_curr_conv != 0) THEN tourney_summary.val_curr_conv * (tr.amt_won + tr.cnt_bounty * tourney_summary.amt_bounty) ELSE 0.0 END))) AS "amt_won_curr_conv", 
      (((CASE when(tourney_summary.val_curr_conv != 0) THEN tourney_summary.val_curr_conv * (tourney_summary.amt_buyin + tourney_summary.amt_fee + tourney_summary.amt_rebuy * tr.cnt_rebuy + tourney_summary.amt_addon * tr.cnt_addon + tourney_summary.amt_bounty) ELSE 0.0 END))) AS "amt_buyin_ttl_curr_conv", 
     ((((CASE when(tourney_summary.val_curr_conv != 0) THEN tourney_summary.val_curr_conv * (tr.amt_won + tr.cnt_bounty * tourney_summary.amt_bounty) ELSE 0.0 END))) - (((CASE when(tourney_summary.val_curr_conv != 0) THEN tourney_summary.val_curr_conv * (tourney_summary.amt_buyin + tourney_summary.amt_fee + tourney_summary.amt_rebuy * tr.cnt_rebuy + tourney_summary.amt_addon * tr.cnt_addon + tourney_summary.amt_bounty) ELSE 0.0 END)))) as net_amt_won, 
     stddev((((CASE when(tourney_summary.val_curr_conv != 0) THEN tourney_summary.val_curr_conv * (tr.amt_won + tr.cnt_bounty * tourney_summary.amt_bounty) ELSE 0.0 END))) - (((CASE when(tourney_summary.val_curr_conv != 0) THEN tourney_summary.val_curr_conv * (tourney_summary.amt_buyin + tourney_summary.amt_fee + tourney_summary.amt_rebuy * tr.cnt_rebuy + tourney_summary.amt_addon * tr.cnt_addon + tourney_summary.amt_bounty) ELSE 0.0 END)))) as diff_std_dev 

FROM tourney_summary, 
    tourney_results tr 
WHERE 
    tr.id_player=1 
    AND tourney_summary.id_tourney = tr.id_tourney 
    AND ((tourney_summary.id_gametype = 1) 
     AND (((((((tourney_summary.id_table_type IN 
        (SELECT lttt.id_table_type 
        FROM tourney_table_type lttt 
        WHERE lttt.val_seats = 2)))))) 
      AND (((((tourney_summary.id_table_type IN 
         (SELECT lttt.id_table_type 
         FROM tourney_table_type lttt 
         WHERE position('S' IN lttt.val_speed) > 0)) 
        OR (tourney_summary.id_table_type IN 
          (SELECT lttt.id_table_type 
          FROM tourney_table_type lttt 
          WHERE position('H' IN lttt.val_speed) > 0)))))))) 
     AND ((tourney_summary.date_start >= '2013/08/15 23:00:00'))) 
GROUP BY tr.date_start, 
     tr.date_end, 
     tourney_summary.val_curr_conv, 
     tr.amt_won, 
     tr.cnt_bounty, 
     tourney_summary.amt_bounty, 
     tourney_summary.amt_buyin, 
     tourney_summary.amt_fee, 
     tourney_summary.amt_rebuy, 
     tr.cnt_rebuy, 
     tourney_summary.amt_addon, 
     tr.cnt_addon 
ORDER BY tr.date_end DESC; 

的 “A” 和 “B” 的表达式(CASE用的那些)都大。而且我不知道如何避免复制/粘贴。在任何情况下,在a-b表达式上使用stddev都会返回一个空白列。我究竟做错了什么?

谢谢。

+0

注意你不需要大部分'(...)'括号(是由ORM生成此查询?)另外:你可以结合三个IN(...)子查询合并为一个(可能使用'EXISTS(...)'代替) – wildplasser

+0

我认为查询可能是半自动生成的。 – dmz73

回答

2

你几乎可以自己回答。计算差值的标准差:

SELECT a, 
     b, 
     a - b as "diff", 
     stddev(a - b) AS "diff_stddev" 
    FROM ... 

如果a - b是计算昂贵的操作,或者其实是在现实中更复杂的表达,你可以在一个子查询包裹它:

SELECT a, b, "diff", stddev("diff") AS diff_stddev 
FROM (
    SELECT a, b, a - b 
    FROM ... 
) x (a, b, "diff") 

x仅仅是子查询表的一个丢弃别名。

1

它也可以做到这一点与CTE

with cte1 as (
    select a, b, a - b as diff 
    from ... 
) 
select 
    a, b, diff, stddev(diff) as diff_stddev 
from cte1