我有以下案例陈述作为动态准备,如下所示:
示例:
我有案例陈述:
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语句,因为值date和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语句应该是动态的而不使用循环。
答案 0 :(得分:1)
您可能不需要任何功能,只需加入映射数据集:
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 ON
或GROUP BY
来避免行重复。
注意:您也可以使用简单的子选择,我使用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();
对于某些客户端(或某些抽象),也可以单独传递每个数据块,但这在很大程度上取决于您的驱动程序/ orm / etc.你用。