Sql 从一组条目计算聚合的tsrange?
我试图从一组从SQL查询中提取的行中计算聚合的Sql 从一组条目计算聚合的tsrange?,sql,postgresql,dynamic-programming,dynamic-sql,range-types,Sql,Postgresql,Dynamic Programming,Dynamic Sql,Range Types,我试图从一组从SQL查询中提取的行中计算聚合的tsrange。问题是,我不断收到输入参数未传入的错误 CREATE OR REPLACE AGGREGATE range_merge(anyrange) ( sfunc = range_merge, stype = anyrange ); DROP FUNCTION IF EXISTS aggregate_validity(entity_name regclass, entry bigint); CREATE OR REPLAC
tsrange
。问题是,我不断收到输入参数未传入的错误
CREATE OR REPLACE AGGREGATE range_merge(anyrange)
(
sfunc = range_merge,
stype = anyrange
);
DROP FUNCTION IF EXISTS aggregate_validity(entity_name regclass, entry bigint);
CREATE OR REPLACE FUNCTION aggregate_validity(entity_name regclass, entry bigint) returns tsrange AS
$$
DECLARE
result tsrange;
BEGIN
EXECUTE format('select range_merge(valid) from %s where entity_id = %U', entity_name, entry) into result;
return result;
END
$$ LANGUAGE plpgsql;
当我这样做时:
select * from aggregate_validity(country, 1);
我收到一个错误,指出实体名称和条目不存在。它似乎没有正确地参数化语句中的输入。函数:
EXECUTE format('select range_merge(valid) from %s where entity_id=%U',entity_name, entry)
into result;
=>
EXECUTE format('select range_merge(valid) from %I where entity_id=%s',entity_name, entry)
into result;
--%I for identifier, %s for value
电话:
电话:
小提琴
调用不需要SELECT*FROM
,因为函数会为每个定义返回一个值
我使用了一个OUT
参数来简化(OUT result tsrange
)。见:
条目
值连接到SQL字符串中。使用子句将其作为值传递。更干净,更快
由于entity\u name
作为regclass
传递,因此可以安全地简单地进行连接(这稍微便宜一点)。见:
range\u merge()
我不会将其命名为“range\u merge”,这也是普通函数的名称。虽然这是合法的,但它仍然会带来令人困惑的错误
您知道函数range\u merge()
包含输出范围中输入范围之间的间隙吗
range\u merge()
为任何空输入返回空值。因此,如果表的valid
列中有任何空值,则结果总是空的。我强烈建议将任何涉及的列定义为非空
如果你有权安装额外的模块,请考虑Paul Jungwirth。它提供了高级函数
range\u agg()
来解决上述一些问题
如果你不想包含空白,考虑一下
我可能根本不会使用aggregate\u validity()
。它模糊了Postgres查询计划器的嵌套功能,并可能导致次优的查询计划。通常,您可以将其替换为相关或横向子查询
子查询,Postgres可以在外部查询的上下文中对其进行规划和优化。我在小提琴上附加了一个演示:
小提琴
相关的:
是否在select语句中执行嵌套的select语句?我有点困惑如何做国家
不起作用选择聚合有效性(“国家”,1)<代码>国家/地区
被视为text@kafka:我添加了一些关于如何使用子查询的详细信息。另外,选择聚合有效期(“国家”,1)
应该可以正常工作,正如在两个小提琴中所演示的那样。请注意,'country'
在这里是一个非类型化的字符串文本。如果传递类型为text
的值,则需要显式强制转换!类似:选择聚合有效性(国家变量作为文本类型::regclass,1)代码>参见:还考虑附加模块<代码> RangeEAGG。我在上面添加了指针。我已经在这个阶段确保了间隙和重叠,因此这不需要考虑-但感谢提醒。
select * from aggregate_validity(country, 1)
=>
select * from aggregate_validity('country', 1);
CREATE OR REPLACE AGGREGATE range_merge(anyrange) (
SFUNC = range_merge
, STYPE = anyrange
);
-- DROP FUNCTION IF EXISTS aggregate_validity(entity_name regclass, entry bigint);
CREATE OR REPLACE FUNCTION aggregate_validity(entity_name regclass, entry bigint, OUT result tsrange)
LANGUAGE plpgsql AS
$func$
BEGIN
EXECUTE 'SELECT range_merge(valid) FROM ' || entity_name || ' WHERE entity_id = $1'
INTO result
USING entry;
END
$func$;
SELECT aggregate_validity('country', 1);