从具有未知列数的表创建频率视图

时间:2011-11-22 09:11:07

标签: postgresql

我有一个包含n列的表,我需要创建一个视图,其中包含每列中每个唯一值的频率。 n是未知的,因为我需要在具有不同列数的多个表上应用解决方案。

例如我有桌子:

column1  column2  column3
value1   value2   value3
value2   value2   value1
value1   value2   value2

视图应该是这样的:

columnname    value    frequency

 column1      value1    2
 column1      value2    1
 column2      value2    3

...

由于我对sql的经验很少,所以非常感谢任何帮助。

非常感谢提前!

到目前为止,我已经提出了这个问题,但现在却有点像石头了。

CREATE or REPLACE FUNCTION create_view () RETURNS setof record AS $$
DECLARE   
col RECORD;
BEGIN
for col in execute 'select column_name from information_schema.columns 
where table_name = ''table123''' LOOP
    ???
END LOOP;
return;
END;
$$
LANGUAGE 'plpgsql';

1 个答案:

答案 0 :(得分:0)

简单SQL:

SELECT 'col1' AS col, col1 AS val, count(*) AS ct FROM  tbl GROUP BY col1
UNION ALL
SELECT 'col2', col2, count(*) FROM  tbl GROUP BY col2
UNION ALL
SELECT 'col3', col3, count(*) FROM  tbl GROUP BY col3

执行动态SQL的PL / pqSQL函数:

CREATE OR REPLACE FUNCTION f_demo(_schema text, _tbl text)
  RETURNS TABLE(col text, val text, ct bigint) AS
$xx$
DECLARE   
   _fld text;
   _sql text := '';
BEGIN

FOR _fld IN  
   SELECT a.attname          -- use quote_ident to safeguard against SQLi
   FROM   pg_catalog.pg_attribute a
   WHERE  a.attrelid =  (COALESCE(_schema || '.', '') || _tbl)::regclass
   AND    a.attnum > 0
   AND    NOT a.attisdropped
-- AND    a.attname ~~ '%col%'   -- if you want to pick specific columns
LOOP
   RETURN QUERY EXECUTE
  'SELECT $1, ' || quote_ident(_fld) || '::text, count(*)
   FROM ' || COALESCE(quote_ident(_schema) || '.', '') || quote_ident(_tbl) || '
   GROUP BY 2'
   USING _fld;
END LOOP;

END;
$xx$
  LANGUAGE 'plpgsql';

呼叫:

SELECT * FROM f_demo('public', 'mytable');

或者,如果您想使用search_path提供的架构:

SELECT * FROM f_demo(NULL, 'mytable');

重点

  • 适用于任意表格任意数量的列任意类型的值
  • 将值转换为文本以简化我的示例。也可以使用多态类型。
  • 有关plpgsql技术和链接的信息,请参阅此相关答案:https://stackoverflow.com/q/8146245/939860