2016-11-02 28 views
0

我正在嘗試使用Postgres函數進行一些數據分析。我試過下面的函數導致錯誤。由於我是數據庫功能,程序等新手。我發現很難解決這個問題。使用PostgreSQL函數進行數據分析

實際工作:

我通過表中的所有列要循環,並執行數據剖析即計數,計數不同,空,空不字符列。最小值,最大值爲數字&日期列。請協助

CREATE OR REPLACE FUNCTION data_profiling (TABLE_VALUE VARCHAR) 
RETURNS TABLE (
col_value VARCHAR, 
DISTINCT_COUNT INT 
) 
AS $$ 
DECLARE 
    var_c Varchar; 

BEGIN 
    FOR var_c IN(SELECT c.column_name,c.table_name 
     FROM information_schema.columns c 
     WHERE lower(c.table_name) = TABLE_VALUE) 
    LOOP 
RETURN QUERY EXECUTE 'SELECT ' || var_c ||' as col_name, count(distinct ' || var_c ||') as distinct_count 
FROM ' || TABLE_VALUE || ' group by ' || var_c; 
      END LOOP; 
END; $$ 
LANGUAGE 'plpgsql'; 

錯誤:

ERROR: structure of query does not match function result type 
DETAIL: Returned type character(50) does not match expected type character varying in column 1. 
CONTEXT: PL/pgSQL function data_profiling(character varying) line 10 at RETURN QUERY 

回答

1

光標返回記錄不是VARCHAR,你需要將您的聲明更改爲:

var_c record; 

該記錄的字段數與您在選擇列表中包含列數一樣多,每個列都可以通過列名引用。使用format()函數來生成動態SQL也更好。

count()也返回bigint而不是int。您還需要將您選擇的列轉換爲varchar,否則您無法返回例如作爲第一列的整數值。

CREATE OR REPLACE FUNCTION data_profiling (table_value varchar) 
    RETURNS TABLE (col_value varchar, distinct_count bigint) 
AS 
$$ 
DECLARE 
    var_c record; 
BEGIN 
    FOR var_c IN (SELECT c.table_schema, c.column_name,c.table_name 
       FROM information_schema.columns c 
       WHERE lower(c.table_name) = TABLE_VALUE 
        and c.table_schema = 'public') 
    LOOP 
     RETURN QUERY EXECUTE 
     format('SELECT %I::varchar, count(distinct %I) FROM %I.%I group by %I', 
       var_c.column_name, var_c.column_name, var_c.table_schema, var_c.table_name, var_c.column_name); 
    END LOOP; 
END; $$ 
LANGUAGE plpgsql; 

佔位符%I(資本i)會照顧的,如果有必要適當引用的列或表名。您還應該確保包含模式名稱。

語言名稱是一個標識符,不要放在單引號中。

您也不需要在生成的SQL中指定列別名,因爲輸出列的名稱由returns table (..)部分定義。這使得代碼更易於閱讀。

0

您需要聲明的長度爲您返回表

RETURNS TABLE (
    col_value VARCHAR(8000), 
    DISTINCT_COUNT INT 
+1

不,這不是必需的。 –