2017-11-26 6 views
0

stage이라는 스키마의 여러 ​​테이블에서 모든 고객 이름을 정리하는 도구를 구현하고 있습니다. 고객 이름은 billing_acc_name 또는 cust_acc_names 열에서 올 수 있습니다. 나는 얼마나 많은 테이블에이 컬럼이 있는지를 미리 알지 못하지만, 그들이하는 한 정리의 일부가 될 것입니다.Postgres PL/pgSQL 여러 테이블에 걸쳐 존재하는 열을 통합하는 방법

그러나 정리하기 전에 스키마의 테이블에서 모든 고유 고객 이름을 선택해야합니다.

더 나은 문제 분리를 위해 PL/pgSQL에서이를 구현하는 방법을 모색 중입니다. 현재이 내가/SQLAlchemy의 파이썬/팬더이를 구현하고있어 어떻게 등

table_name = 'information_schema.columns' 
table_schema_src = 'stage' 
cols = ['billing_acc_name', 'cust_acc_name'] 

# get list of all table names and column names to query in stage schema 
sql = text(f""" 
    SELECT table_name, column_name FROM {table_name} WHERE table_schema ='{table_schema_src}' 
    AND column_name = ANY(ARRAY{cols}) 
""") 
src = pd.read_sql(sql, con=engine) 

# explore implementation in pgsql 
# establish query string 
cnames = [] 
for i, row in src.iterrows(): 
    s = text(f""" 
     SELECT DISTINCT upper({row['column_name']}) AS cname FROM stage.{row['table_name']} 
    """) 
    cnames.append(str(s).strip()) 

sql = ' UNION '.join(cnames) 

df = pd.read_sql(sql, con=engine) 

자동 생성 된 SQL 쿼리 문자열은 다음과 같이 다음과 같습니다

SELECT DISTINCT upper(cust_acc_name) AS cname FROM stage.journal_2017_companyA UNION 
SELECT DISTINCT upper(billing_acc_name) AS cname FROM stage.journal_2017_companyA UNION 
SELECT DISTINCT upper(cust_acc_name) AS cname FROM stage.journal_2017_companyB UNION 
SELECT DISTINCT upper(billing_acc_name) AS cname FROM stage.journal_2017_companyB UNION 
SELECT DISTINCT upper(cust_acc_name) AS cname FROM stage.journal_2017_companyC UNION 
SELECT DISTINCT upper(billing_acc_name) AS cname FROM stage.journal_2017_companyC UNION 
SELECT DISTINCT upper(cust_acc_name) AS cname FROM stage.journal_2017_companyD UNION 
SELECT DISTINCT upper(billing_acc_name) AS cname FROM stage.journal_2017_companyD 

답변

1

plpgsql 기능처럼 보일 수 있습니다 이 :

create or replace function select_acc_names(_schema text) 
returns setof text language plpgsql as $$ 
declare 
    rec record; 
begin 
    for rec in 
     select table_name, column_name 
     from information_schema.columns 
     where table_schema = _schema 
     and column_name = any(array['cust_acc_name', 'billing_acc_name']) 
    loop 
     return query 
     execute format ($fmt$ 
      select upper(%I) as cname 
      from %I.%I 
      $fmt$, rec.column_name, _schema, rec.table_name); 
    end loop; 
end $$; 

사용 :

select * 
from select_acc_names('stage'); 
+0

테스트를 거쳐 훌륭하게 작동했습니다. 너무 끔찍해. – idazuwaika