我有一个表,对于ID,将在多个存储桶字段中包含数据。我想要一个函数来提取一个桶的总和,但函数参数将包括开始和结束桶字段。
所以,如果我有这样的表:
ID Bucket0 Bucket30 Bucket60 Bucket90 Bucket120
10 5.00 12.00 10.00 0.0 8.00
如果我发送ID和参数Bucket0,Bucket0,它将仅返回Bucket0字段中的值:5.00
如果我发送了ID和参数Bucket30,Bucket120,它会将桶的总和从30返回到120,或者(12 + 10 + 0 + 8)30.00。
除了一个巨大的丑陋之外,有没有更好的方式来写这个
if parameter1=bucket0 and parameter2=bucket0
then select bucket0
else if parameter1=bucket0 and parameter2=bucket1
then select bucket0 + bucket1
else if parameter1=bucket0 and parameter2=bucket2
then select bucket0 + bucket1 + bucket2
等等?
该表已经存在,因此我无法对此进行大量控制。我可以为我想要的功能制作参数。我可以有把握地说,如果需要一组桶,中间的任何一个都不会被跳过,所以指定开始和结束桶都可以。我可以用一个逗号分隔的所有桶的字符串。
答案 0 :(得分:1)
如果您的表格已经标准化会更好,例如:
id | bucket | value
---+-----------+------
10 | bucket000 | 5
10 | bucket030 | 12
10 | bucket060 | 10
10 | bucket090 | 0
10 | bucket120 | 8
此外,存储桶最好具有易于在范围内进行比较的名称,因此bucket030
按照正常的字母顺序介于bucket000
和bucket120
之间,但事实并非如此如果你遗漏了填充的零。
如果无法进行上述规范化,则使用unpivot
子句将当前表格转换为上述结构:
select id, sum(value)
from (
select *
from mytable
unpivot (value for bucket_id in (bucket0 as 'bucket000',
bucket30 as 'bucket030',
bucket60 as 'bucket060',
bucket90 as 'bucket090',
bucket120 as 'bucket120'))
) normalised
where bucket_id between 'bucket000' and 'bucket060'
group by id
使用参数变量执行此操作时,请确保这些参数也具有填充的零。
例如,您可以确保 parameter1 :
的内容如下所示if parameter1 like 'bucket%' then
parameter1 := 'bucket' || lpad(+substr(parameter1, 7), 3, '0');
end if;
...等