使用 PostgreSQL 9.3 准备动态 case 语句

Prepare dynamic case statement using PostgreSQL 9.3

我有以下案例语句准备作为动态,如下所示:

示例:

我有案例陈述:

case cola 
when cola between '2001-01-01' and '2001-01-05' then 'G1'
when cola between '2001-01-10' and '2001-01-15' then 'G2'
when cola between '2001-01-20' and '2001-01-25' then 'G3'
when cola between '2001-02-01' and '2001-02-05' then 'G4'
when cola between '2001-02-10' and '2001-02-15' then 'G5'
else '' 
end

注意:现在我想创建动态 case 语句,因为值 dates 和 name 作为参数传递并且它可能会更改。

Declare 
dates varchar = '2001-01-01to2001-01-05,2001-01-10to2001-01-15,
                           2001-01-20to2001-01-25,2001-02-01to2001-02-05,
                           2001-02-10to2001-02-15';

names varchar = 'G1,G2,G3,G4,G5';

变量中的值可能会根据要求更改,它将是动态的。所以 case 语句应该是动态的而不使用循环。

您可能不需要任何功能,只需加入映射数据集即可:

with cola_map(low, high, value) as (
  values(date '2001-01-01', date '2001-01-05', 'G1'),
        ('2001-01-10', '2001-01-15', 'G2'),
        ('2001-01-20', '2001-01-25', 'G3'),
        ('2001-02-01', '2001-02-05', 'G4'),
        ('2001-02-10', '2001-02-15', 'G5')
        -- you can include as many rows, as you want
)
select    table_name.*,
          coalesce(cola_map.value, '') -- else branch from case expression
from      table_name
left join cola_map on table_name.cola between cola_map.low and cola_map.high

如果您的日期范围可能会发生冲突,您可以使用 DISTINCT ONGROUP BY 来避免行重复。

注意:你也可以使用简单的子select,我使用了CTE,因为它更易读。

编辑:传递这些数据(作为单个参数)可以通过传递多维数组(或行值数组,但这需要您有一个独特的预定义 composite type).

将数组作为参数传递可能取决于您使用的实际客户端(和驱动程序),但一般来说,您可以使用 array's input representation:

-- sql
with cola_map(low, high, value) as (
  select  d[1]::date, d[2]::date, d[3]
  from    unnest(?::text[][]) d
)
select    table_name.*,
          coalesce(cola_map.value, '') -- else branch from case expression
from      table_name
left join cola_map on table_name.cola between cola_map.low and cola_map.high
// client pseudo code
query = db.prepare(sql);
query.bind(1, "{{2001-01-10,2001-01-15,G2},{2001-01-20,2001-01-25,G3}}");
query.execute();

某些客户端(或某些抽象)也可以单独传递每个数据块,但这在很大程度上取决于您的 driver/orm/etc。你用。