Czy ktoś wie, jak tworzyć zapytania w tabeli krzyżowej w PostgreSQL?
Na przykład mam następującą tabelę:
Section Status Count
A Active 1
A Inactive 2
B Active 4
B Inactive 5
Chciałbym, aby zapytanie zwróciło następującą tabelę przestawną:
Section Active Inactive
A 1 2
B 4 5
czy to możliwe?
Odpowiedzi:
Zainstaluj dodatkowy moduł
tablefunc
raz na bazę danych, która udostępnia tę funkcjęcrosstab()
. Od wersji Postgres 9.1 możeszCREATE EXTENSION
do tego użyć :Ulepszony przypadek testowy
Prosta forma - nie nadaje się do brakujących atrybutów
crosstab(text)
z 1 parametrem wejściowym:Zwroty:
C
: wartość7
jest wypełniana dla pierwszej kolumny. Czasami takie zachowanie jest pożądane, ale nie w tym przypadku użycia.Bezpieczna forma
crosstab(text, text)
z 2 parametrami wejściowymi:Zwroty:
Zwróć uwagę na poprawny wynik dla
C
.Drugim parametrem może być dowolny zapytania, który powraca jeden rząd na atrybutu dopasowanie kolejność definicji kolumnowej na końcu. Często będziesz chciał zapytać o różne atrybuty z tabeli bazowej w następujący sposób:
To jest w instrukcji.
Ponieważ i tak musisz przeliterować wszystkie kolumny na liście definicji kolumn (z wyjątkiem wstępnie zdefiniowanych wariantów), zazwyczaj bardziej wydajne jest dostarczenie krótkiej listy w wyrażeniu takim jak pokazano:
crosstabN()
VALUES
Lub (nie w instrukcji):
Użyłem wyceny w dolarach, aby ułatwić wycenę.
Możesz nawet wyprowadzać kolumny z różnymi typami danych za pomocą
crosstab(text, text)
- o ile reprezentacja tekstowa kolumny wartości jest poprawnym wejściem dla typu docelowego. W ten sposób można mieć atrybuty różnego rodzaju i wyjściatext
,date
,numeric
itp dla poszczególnych atrybutów. Przykład kodu znajduje się na końcu rozdziałucrosstab(text, text)
instrukcji .db <> skrzypce tutaj
Zaawansowane przykłady
Przestaw się na wiele kolumn za pomocą Tablefunc - demonstrując również wspomniane „dodatkowe kolumny”
Dynamiczna alternatywa dla pivot z CASE i GROUP BY
\crosstabview
w psqlPostgres 9.6 dodał tę meta-komendę do domyślnego terminala interaktywnego psql . Możesz uruchomić zapytanie, którego użyjesz jako pierwszy
crosstab()
parametr, i podaj je\crosstabview
(natychmiast lub w następnym kroku). Lubić:Podobny wynik jak powyżej, ale jest to funkcja reprezentacji wyłącznie po stronie klienta . Wiersze wejściowe są traktowane nieco inaczej, dlatego
ORDER BY
nie są wymagane. Szczegóły\crosstabview
w instrukcji. Na dole tej strony znajduje się więcej przykładów kodu.Powiązana odpowiedź na dba.SE autorstwa Daniela Vérité (autora funkcji psql):
Uprzednio zaakceptowane odpowiedź jest przestarzała.
Wariant tej funkcji
crosstab(text, integer)
jest przestarzały. Drugiinteger
parametr jest ignorowany. Cytuję obecny podręcznik :Niepotrzebne odlewanie i zmiana nazwy.
Nie powiedzie się, jeśli wiersz nie ma wszystkich atrybutów. Zobacz bezpieczny wariant z dwoma parametrami wejściowymi powyżej, aby poprawnie obsługiwać brakujące atrybuty.
ORDER BY
jest wymagany w postaci jednoparametrowejcrosstab()
. Instrukcja:źródło
In practice the SQL query should always specify ORDER BY 1,2 to ensure that the input rows are properly ordered
Możesz użyć
crosstab()
funkcji dodatkowego modułu tablefunc - który musisz zainstalować raz na bazę danych. Od PostgreSQL 9.1 możeszCREATE EXTENSION
do tego użyć :W twoim przypadku wydaje mi się, że wyglądałoby to mniej więcej tak:
źródło
źródło
sum()
mówiąc : ten formularz używa funkcji agregującej , lepiej byłoby użyćmin()
lubmax()
i nie, dlaELSE
którejtext
również działa . Ma to jednak subtelnie inne efekty niżcorosstab()
, które wykorzystują tylko „pierwszą” wartość na atrybut. Nie ma znaczenia, dopóki może być tylko jeden. Wreszcie istotna jest także wydajność.crosstab()
jest napisany w C i zoptymalizowany do tego zadania.ERROR: 42803: aggregate function calls may not be nested
Rozwiązanie z agregacją JSON:
źródło
Przykro nam, ale nie jest to kompletne, ponieważ nie mogę go tutaj przetestować, ale może doprowadzić cię do właściwego kierunku. Tłumaczę z czegoś, z czego korzystam, tworząc podobne zapytanie:
Kod, z którego pracuję to:
co zwróci identyfikator typu, najwyższą cenę ofertową i najniższą cenę zadaną oraz różnicę między nimi dwoma (dodatnia różnica oznaczałaby, że można kupić coś za mniej niż można sprzedać).
źródło
Crosstab
funkcja jest dostępna podtablefunc
rozszerzeniem. Będziesz musiał utworzyć to rozszerzenie jeden raz dla bazy danych.UTWÓRZ ROZSZERZENIE
tablefunc
;Możesz użyć poniższego kodu, aby utworzyć tabelę przestawną za pomocą tabulacji krzyżowej:
źródło