我已经找到了我要在Oracle和SQL Server上解决的问题的解决方案(但我认为),但是似乎无法将其转换为Postgres解决方案。我正在使用Postgres 9.3.6。
想法是能够生成有关表内容的“元数据”以进行概要分析。这只能通过让每一列都运行查询来找出(例如...)最小/最大/计数值等来完成(AFAIK)。为了使过程自动化,最好由数据库生成查询,然后执行。
使用示例salesdata
表,我能够使用以下代码段为每列生成一个选择查询,并返回min()值:
SELECT 'SELECT min('||column_name||') as minval_'||column_name||' from salesdata '
FROM information_schema.columns
WHERE table_name = 'salesdata'
优点是,无论列数如何,数据库都将生成代码。现在,我想到了无数个地方来存储这些查询,这些查询可以是某种变量,也可以是表列,其想法是执行这些查询。我想到将生成的查询存储在变量中,然后使用EXECUTE
(或EXECUTE IMMEDIATE
)语句执行它们,这是here所采用的方法(请参见右窗格),但是Postgres不会让我在外部声明变量一个功能,我一直在摸索如何将它们组合在一起,无论这是要遵循的方向,还是有一些更简单的方法。
您有任何指示,我目前正在尝试类似的工作,受other question的启发,但不知道我是否朝着正确的方向前进:
CREATE OR REPLACE FUNCTION foo()
RETURNS void AS
$$
DECLARE
dyn_sql text;
BEGIN
dyn_sql := SELECT 'SELECT min('||column_name||') from salesdata'
FROM information_schema.columns
WHERE table_name = 'salesdata';
execute dyn_sql
END
$$ LANGUAGE PLPGSQL;
您自己滚动之前,请查看系统表pg_statistic
或视图pg_statistic
:
此视图仅允许访问对应的
pg_stats
行 到用户有权读取的表,因此可以安全地进行 允许公众对此视图进行读取访问。
它可能已经具有您要计算的某些统计信息。它由pg_stats
填充,因此您可以在检查之前将其用于新(或任何)表。
pg_statistic
您要返回给定表中每一列的最小值。这不是一件容易的事,因为一个函数(一般来说就是SQL)要求在创建时或在调用时至少在多态数据类型的帮助下知道返回类型。
此功能自动安全地完成所有操作。对于any表有效,只要每一列都允许使用聚合函数ANALYZE
。但是您需要了解有关PL / pgSQL的方法。
-- ANALYZE tbl; -- optionally, to init / refresh
SELECT * FROM pg_stats
WHERE tablename = 'tbl'
AND schemaname = 'public';
呼叫(重要!):
min()
db <>小提琴CREATE OR REPLACE FUNCTION f_min_of(_tbl anyelement)
RETURNS SETOF anyelement
LANGUAGE plpgsql AS
$func$
BEGIN
RETURN QUERY EXECUTE (
SELECT format('SELECT (t::%2$s).* FROM (SELECT min(%1$s) FROM %2$s) t'
, string_agg(quote_ident(attname), '), min(' ORDER BY attnum)
, pg_typeof(_tbl)::text)
FROM pg_attribute
WHERE attrelid = pg_typeof(_tbl)::text::regclass
AND NOT attisdropped -- no dropped (dead) columns
AND attnum > 0 -- no system columns
);
END
$func$;
旧SELECT * FROM f_min_of(NULL::tbl); -- tbl being the table name
您需要了解这些概念:
具有详细说明的相关答案:
EXECUTE
我利用Postgres为每个现有表定义行类型。使用多态类型的概念,我能够创建适用于任何表的one函数。
但是,与基础列相比,某些聚合函数返回相关但不同的数据类型。例如,Select columns with particular column names in PostgreSQL返回Generate series of dates - using date type as input,它是位兼容的,但<相同的数据类型。 PL / pgSQL函数在这里有一个弱点,并坚持使用min(varchar_column)
子句中声明的数据类型exactly。没有尝试转换,甚至没有隐式转换,更不用说任务转换了。应该改善。用Postgres 9.3测试。没用9.4重新测试,但是我很确定,这个区域没有任何变化。
这就是该构造体作为
解决方法
:text
通过将整个行显式转换为基础表的行类型,我们强制分配转换以获取每一列的原始数据类型。
这对于某些聚合函数可能会失败。 RETURNS
为SELECT (t::tbl).* FROM (SELECT ... FROM tbl) t;
返回sum()
,以容纳溢出基本数据类型的总和。投射回numeric
可能会失败...