na podstawie odpowiedzi dynamiczne nagłówki kolumn Postgres (z innego stołu) (praca Erica Vallabha Minikela) ulepszyłem funkcję, aby była bardziej elastyczna i wygodna. Myślę, że może to być przydatne również dla innych, zwłaszcza że opiera się tylko na pg/plsql i nie wymaga instalacji rozszerzeń, jak robią to inne pochodne pracy erics (np. plpython). Testet z 9.3.5, ale powinien również działać przynajmniej do 9.2.
Ulepszenia:
- radzić sobie z przestawnymi nazwami kolumn zawierającymi spacje
- radzić sobie z wieloma kolumnami nagłówków wierszy
- zajmij się funkcją agregacji w komórce przestawnej, jak również w niezagregowanej komórce przestawnej (ostatnim parametrem może być „sum(cellval)” oraz „cellval”, jeśli podstawowa tabela/widok już wykonuje agregację)
- automatyczne wykrywanie typu danych w komórce przestawnej (nie trzeba już przekazywać ich do funkcji)
Wykorzystanie:
SELECT get_crosstab_statement('table_to_pivot', ARRAY['rowname' [, ], 'colname', 'max(cellval)');
Kod:
FUNKCJA UTWÓRZ LUB ZAMIEŃ get_crosstab_statement (znak nazwy tabeli zmienny, znak zmienny w kolumnie_nagłówka_wiersza[], znak zmienny w kolumnie nagłówka_przestawu, znak zmienny wartości_przestawu) ZWRACA znak zmienny AS$BODY$--zwraca instrukcję sql używaną do obracania tabeli- -na podstawie:http://www.cureffi.org/2013/03/19/automatically-creating-pivot-table-column-names-in-postgresql/--na podstawie:https://stackoverflow.com/questions /4104508/postgres-dynamic-column-headers-from-another-table--na podstawie:http://www.postgresonline.com/journal/categories/24-tablefuncDECLARE nazwa tablicy CONSTANT zmienny znak :='r'; znak row_headers_simple zmienny; row_headers_quoted znak zmienny; znak row_headers_castdown zmienny; row_headers_castup znak zmienny; row_header_count smallint; rekord row_header; pivot_values_columnname znak zmienny; pivot_values_datatype znak zmienny; pivot_headers_definition znak zmienny; pivot_headers_simple charakter zmienny; sql_row_headers znak zmienny; sql_pivot_headers znak zmienny; sql_crosstab_result znak zmienny;BEGIN -- 1. utwórz definicje nagłówków wierszy row_headers_simple :=array_to_string(row_header_columns, ', '); row_headers_quoted :='''' || array_to_string(row_header_columns, ''', ''') || ''''; row_headers_castdown :=array_to_string(row_header_columns, '::text, ') || '::tekst'; row_header_count :=0; sql_row_headers :='SELECT nazwa_kolumny, typ_danych FROM schemat_informacji.kolumny WHERE nazwa_tabeli =''' || nazwa tabeli || ''' AND nazwa_kolumny IN (' || wiersz_nagłówki_cytowane || ')'; FOR row_header IN EXECUTE sql_row_headers LOOP row_header_count :=row_header_count + 1; row_headers_castup :=COALESCE(row_headers_castup || ', ', '') || nazwa tablicy || '[' || row_header_count || ']::' || row_header.data_type || ' AS ' || wiersz_nagłówek.nazwa_kolumny; PĘTLA KOŃCOWA; -- 2. pobierz podstawową nazwę kolumny w przypadku użycia funkcji agregującej SELECT koalescencja(podciąg(wartości_przestawne FROM '.*\((.*)\)'), wartości_przestawne) INTO nazwa_kolumny_wartości_przestawnych; -- 3. pobierz wartości przestawne typ danych SELECT typ_danych FROM schemat_informacji.kolumny WHERE nazwa_tabeli =nazwa_tabeli AND nazwa_kolumny =nazwa_kolumny_wartości_przestawu INTO typ_wartości_przestawnych; -- 4. pobierz listę nazw kolumn przestawnych. sql_pivot_headers :='SELECT string_agg(DISTINCT cytat_ident(' || pivot_headers_column || '), '', '' ORDER BY cytat_ident(' || pivot_headers_column || ')) jako nazwy, string_agg(DISTINCT cytat_ident(' |||n_pivot_headers) | ') || '' ' || typ_danych_wartości || ''', '', '' ORDER BY cytat_ident(' || kolumna_nagłówków_przestawu || ') || '' ' || typ_danych_wartości || ''') jako definicje OD ' || nazwa tabeli || ';'; WYKONAJ sql_pivot_headers INTO pivot_headers_simple, pivot_headers_definition; -- 5. skonfiguruj zapytanie krzyżowe sql_crosstab_result :='SELECT ' || zamień (row_headers_castup || ', ' || pivot_headers_simple, ', ', ', ') || 'FROM tabela przestawna ( ''SELECT ARRAY[' || rzutowanie_nagłówków_wiersza || '] AS ' || nazwa tablicy || ', ' || kolumna_nagłówków_przestawu || ', ' || wartości_przestawu || ' FROM ' || nazwa_tabeli || ' GROUP BY ' || wiersz_nagłówki_proste || ', ' || kolumna_nagłówków_przestawu || (WIELKIE WIELKOŚCI nazwa_kolumny_wartości_przestawu=wartości_przestawu KIEDY prawda TO ', ' || wartości_przestawu ELSE '' END) || ' ORDER BY ' || nagłówki_wierszów''', || BY 'SELECT DISTINCT ' || kolumna_nagłówków_przestawu || ' FROM ' || nazwa_tabeli || ' ORDER BY ' || kolumna_nagłówków_przestawu || ''' ) AS nowatabela ( ' || nazwa_tablicy || ' varchar[]' || ', ' | | replace(definicja_nagłówków_przestawnych, ', ', ', ') || ' );'; POWRÓT sql_crosstab_result; KONIEC $BODY$ JĘZYK plpgsql STABILNY KOSZT 100;