Postgres:如何获取枚举集合中的下一个项?

6
考虑使用以下代码。类型enum_buysell只包括两个值:buysell。有些情况下我需要获得相反的值,但是我认为代码看起来很丑。有没有一种优化的方法?我考虑过不使用枚举,改用布尔类型,但这个想法并不完美,因为它会使数据本身不太明显。
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;

逻辑问题:枚举类型基本上是无序的。 - wildplasser
@wildplasser,基本上你是对的,但这不适用于postgres——看一下文档:8.7.2. 排序就知道了。 - Denis Zhbankov
1个回答

3

由于PostgreSQL没有获取下一个枚举值的函数,您需要自己定义它。

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;

现在,您可以像这样使用它:

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

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

您的CASE语句将变成:

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

谢谢,看起来更好了,这是肯定的。但是执行一个额外的函数是否存在性能劣势,因为它基本上执行与内联代码本身相同的操作?我的意思是,这些奇怪的类型转换从 varcharenum_buysell 仍然存在,它们真的无法避免吗? - Denis Zhbankov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接