2013-08-17 3 views
0

Я хочу сделать запрос, где я вычисляю разницу между двумя столбцами. Что-то вроде:Использование агрегатных функций для псевдонима?

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

Теперь я хотел бы вычислить STDDEV колонки «дифф» с использованием PostgreSQL встроенных StdDev агрегатной функцией. Как я могу это достичь?

Спасибо.

EDIT:

Фактический запрос заключается в следующем:

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; 

"а" и "б" выражения (те, с футляром) являются большими. И я не знаю, как избежать копирования/вставки. В любом случае использование stddev в выражении a-b возвращает пустой столбец. Что я делаю не так?

Спасибо.

+0

Примечание Вам не нужно большинство '(...)' скобки (был этот запрос генерируется ОРМ?) Кроме того, вы можете комбинировать три '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

это также можно сделать с КТР

with cte1 as (
    select a, b, a - b as diff 
    from ... 
) 
select 
    a, b, diff, stddev(diff) as diff_stddev 
from cte1 
Смежные вопросы