我想做一个查询,计算两列之间的差异。类似于:

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

现在我想使用postgresql内置的stddev聚合函数计算“diff”列的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”的表达(有大小写的)很大。我不知道如何避免复制/粘贴。在任何情况下,对a-b表达式使用stddev都会返回空列。我做错什么了?
谢谢。

最佳答案

你差不多自己回答。计算差值的标准偏差:

 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只是子查询表的废弃别名。

08-06 01:39