2015-04-29 13 views
6

aşağıdaki kodu kullanmayı düşünün. buy ve sell: Tip enum_buysell sadece 2 değerlerini içerir. Bazı durumlarda sadece karşıt değeri almam gerekiyor, ama kod çirkin görünüyor, imho. Bunu optimize etmenin bir yolu var mı? Enum kullanmadığını düşündüm, örn. Bunun yerine boolean yapın, ancak bu fikir, verilerin kendisini daha az belirgin hale getirdiği için mükemmel değildir.Postgres: Nasıl bir enum sette sonraki öğeyi almak için?

select 
    datetime, 
    case 
    when account_id_active = p_account_id and direction = 'buy' then 'buy'::enum_buysell 
    when account_id_active = p_account_id and direction = 'sell' then 'sell'::enum_buysell 
    when account_id_passive = p_account_id and direction = 'buy' then 'sell'::enum_buysell 
    when account_id_passive = p_account_id and direction = 'sell' then 'buy'::enum_buysell 
    end as direction, 
    price, 
    volume 
from 
    deals 
where 
    account_id_active = p_account_id or 
    account_id_passive = p_account_id 
order by 
    datetime desc 
limit 
    10; 
+0

Mantık sorun: Bir enum * sırasız temelden * olduğunu. – wildplasser

+0

@wildplasser temelden kesinlikle haklısın, ama bu, postgres'in doğru değil - var [dokümanlar bir göz: 8.7.2. , Sipariş] (http://www.postgresql.org/docs/9.4/static/datatype-enum.html) –

cevap

3

PostgreSQL'de bir sonraki değer değerine ulaşmak için bir işlev olmadığından, bunu kendiniz tanımlamanız gerekir.

postgres=# select next_buysell('sell'::enum_buysell); 
next_buysell 
-------------- 
buy 
(1 row) 

postgres=# select next_buysell('buy'::enum_buysell); 
next_buysell 
-------------- 
sell 
(1 row) 

Ve CASE deyimi olur:

create function next_buysell (e enum_buysell) 
returns enum_buysell 
as $$ 
begin 
    return (case when e='buy'::enum_buysell then 'sell'::enum_buysell 
       else 'buy'::enum_buysell 
      end); 
end 
$$ language plpgsql; 

Şimdi, bu gibi kullanabilirsiniz

case 
    when account_id_active = p_account_id then direction 
    when account_id_passive = p_account_id then next_buysell(direction) 
end as direction 
+0

sayesinde bu kesin, daha iyi görünüyor, ama bir daha işlev yürütülürken ile ilgili bazı performans dezavantajı yoktur Temel olarak, satır içi kodun kendisi ile aynı şeyi yapar? ben hala orada, onlar gerçekten kaçınılmazdır edilir enum_buysell' 'için varchar'' dan bu garip tip dökümler ki? –