2017-10-03 3 views
1

I haben die folgende Tabelle:Postgres berechnete Spalten aus schließt sich

id | underlying | option_symbol | option_type | expiration_date | strike | mid | 

Ich brauche auf verknüpften Felder Berechnungen durchzuführen und diese berechnete Felder zur weiteren Sortierung verwenden. Hier

ist ein Versuch, was ich meine:

SELECT a.underlying, 
a.expiration_date, 
(a.strike - b.strike) as spread_profit, 
(a.mid - b.mid) as spread_distance, 
(spread_distance - spread_profit) as spread_max_loss, 
(spread_profit/spread_max_loss) as spread_profit_ratio 
FROM option_data a 
JOIN option_data b ON a.underlying = b.underlying AND a.expiration_date = b.expiration_date 
WHERE a.option_type = 'put' 
AND b.option_type = 'call' 
AND a.expiration_date <= '2017-10-31' 
group by a.underlying, a.expiration_date order by spread_profit_ratio desc 

Was sollte den richtigen Weg sein, um diese Abfrage zu formulieren?

Antwort

2

Sie haben die ganze Ausdrücke zu ersetzen, wie

SELECT ..., 
    (a.strike - b.strike) AS spread_profit, 
    (a.mid - b.mid) AS spread_distance, 
    (a.mid - b.mid - a.strike + b.strike) AS spread_max_loss, 
    ((a.strike - b.strike)/(a.mid - b.mid - a.strike + b.strike)) 
     AS spread_profit_ratio 
... 

Gleiches gilt für die ORDER BY Klausel hält, aber Sie können die Verknüpfung ORDER BY 6 durch das sechste SELECT Listenelement zu sortieren verwenden.

Wenn das zu umständlich ist, können Sie Subselects verwenden:

SELECT underlying, 
     expiration_date, 
     spread_profit, 
     spread_distance, 
     spread_max_loss, 
     spread_profit/spread_max_loss AS spread_profit_ratio 
FROM (SELECT underlying, 
      expiration_date, 
      spread_profit, 
      spread_distance, 
      (spread_distance - spread_profit) AS spread_max_loss 
     FROM (SELECT a.underlying, 
        a.expiration_date, 
        (a.strike - b.strike) as spread_profit, 
        (a.mid - b.mid) as spread_distance 
      FROM ... 
      ) sub_1 
    ) sub_2 
WHERE ... 
ORDER BY spread_profit_ratio DESC; 

Sie haben die Wahl!

+0

Rechts. Aber in diesen Fällen bevorzuge ich oft einen CTE. Beispiel: 'mit myCTE als (wählen Sie wie berechnet, ... form ... where ...) wählen Sie berechnet, someFn (berechnet) * 23 als someOtherCalc, ... aus myCTE' – bitifet

+1

Vielleicht wird das machen Abfrage besser lesbar, aber da [CTEs sind Optimierungszäune] (https://blog.2ndquadrant.com/postgresql-ctes-are-optimization-fences/), kann die Leistung leiden. –