2017-11-26 2 views
0

Ich implementiere ein Tool, um alle Kundennamen über verschiedene Tabellen in einem Schema namens stage zu bereinigen. Die Kundennamen könnten aus den Spalten billing_acc_name oder cust_acc_names stammen. Ich weiß nicht im Voraus, wie viele Tabellen diese Spalten haben, aber solange sie dies tun, werden sie Teil der Bereinigung sein.Postgres PL/pgSQL zum Konsolidieren von Spalten, die in verschiedenen Tabellen vorhanden sind

Vor der Bereinigung muss ich jedoch alle eindeutigen Kundennamen in den Tabellen im Schema auswählen.

Für eine bessere Trennung von Bedenken, ich überlege, dies in PL/pgSQL zu implementieren. Derzeit ist dies, wie ich dies in Python/Pandas bin Umsetzung/SQLAlchemy usw.

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) 

Die automatisch generierten SQL-Query-String sind dann wie folgt:

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 

Antwort

1

Die plpgsql Funktion kann wie folgt aussehen dies:

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 $$; 

Verwendung:

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

getestet und hat super funktioniert. zu fantastisch. – idazuwaika

Verwandte Themen