我已经徒劳地尝试了几个小时来创建一个函数,该函数根据下标数组的标准过滤数组下标,然后创建这些下标的数组。
我正在处理的数据结构类似于以下示例(除了要比较的列更多以及更复杂的规则和混合数据类型):
id hierarchy abbreviation1 abbreviation2
1 {1} SB GL
2 {2,1} NULL NULL
3 {3,2,1} NULL TC
4 {4,2,1} NULL NULL
我需要运行一个查询,该查询将下一个最接近父级的非空值用于 abbreviation1 和 abbreviation2,并根据与当前记录的层次距离进行比较,以获得缩写的单个值。因此,例如,如果 abbreviation1 和 abbreviation2 的第一个非空值都在同一记录级别,则 abbreviation1 将优先;另一方面,如果第一个非空 abbreviation2 更接近当前记录,那么 abbreviation1 对应的非空值,则将使用 abbreviation2。
因此,对上述示例表的描述查询将产生;
id abbreviation
1 SB
2 SB
3 TC
4 SB
为了完成这个任务,我需要生成一个过滤的数组下标数组(在array_agg()
对缩写列执行之后),它只包含缩写列中的值不为空的下标。
以下功能,基于我疲惫的头脑中的所有逻辑,应该可以工作,但不能
CREATE OR REPLACE FUNCTION filter_array_subscripts(rawarray anyarray,criteria anynonarray,dimension integer, reverse boolean DEFAULT False)
RETURNS integer[] as
$$
DECLARE
outarray integer[] := ARRAY[]::integer[];
x integer;
BEGIN
for i in array_lower(rawarray,dimension)..array_upper(rawarray,dimension) LOOP
IF NOT criteria IS NULL THEN
IF NOT rawarray[i] IS NULL THEN
IF NOT rawarray[i] = criteria THEN
IF reverse = False THEN
outarray := array_append(outarray,i);
ELSE
outarray := array_prepend(i,outarray);
END IF;
ELSE
IF reverse = False THEN
outarray := array_append(outarray,i);
ELSE
outarray := array_prepend(i,outarray);
END IF;
END IF;
END IF;
ELSE
IF NOT rawarray[i] is NULL THEN
IF reverse = False THEN
outarray := array_append(outarray,i);
ELSE
outarray := array_prepend(i,outarray);
END IF;
END IF;
END IF;
END LOOP;
RETURN outarray;
END;
$$ LANGUAGE plpgsql;
例如,下面的查询{5,3,1}
何时返回{5,4,2,1}
select filter_array_subscripts(array['This',NULL,'is',NULL,'insane!']::text[]
,'is',1,True);
我不知道为什么这不起作用,我尝试使用foreach
数组迭代语法,但我不知道如何将迭代值转换为包含在anyarray
.
可以做些什么来解决这个问题?