2014-04-14 16 views

Odpowiedz

33

Zastosowanie crosstab() z modułu tablefunc.

SELECT * FROM crosstab(
    $$SELECT user_id, user_name, rn, email_address 
    FROM (
     SELECT u.user_id, u.user_name, e.email_address 
      , row_number() OVER (PARTITION BY u.user_id 
          ORDER BY e.creation_date DESC NULLS LAST) AS rn 
     FROM usr u 
     LEFT JOIN email_tbl e USING (user_id) 
     ) sub 
    WHERE rn < 4 
    ORDER BY user_id 
    $$ 
    , 'VALUES (1),(2),(3)' 
    ) AS t (user_id int, user_name text, email1 text, email2 text, email3 text); 

Użyłem kwotowania dolara dla pierwszego parametru, który nie ma specjalnego znaczenia. To jest po prostu wygodne, jeśli trzeba uciec apostrofów w ciągu kwerendy, która jest wspólna sprawa:

Szczegółowe wyjaśnienie i instrukcje tutaj:

W szczególności w przypadku "dodatkowych kolumn":

W szczególne trudności są tu:

  • brak kluczowych nazwisk.
    -> Zastępujemy w podzapytaniu za pomocą row_number().

  • Różna liczba wiadomości e-mail.
    -> Ograniczamy do maks. z trzech w zewnętrznym SELECT
    i użyj crosstab() z dwoma parametrami, dostarczając listę możliwych kluczy.

Zwróć uwagę na NULLS LAST in the ORDER BY.

+2

doskonała, Dziękuje. Dokładnie to, czego potrzebuję. To zapytanie byłoby nieco poza mną, ale pomogło mi dużo się nauczyć i zrozumieć. – dacology

+0

Dla tych niewielu, którzy się zastanawiają. Nie, to nie działa na AWS Redshift. –

+0

@MarcelloGrechiLins: Te pytania i odpowiedzi dotyczą Postgres, a nie Redshift. –

8

Jeśli ktoś, że znajdzie to pytanie i potrzebuje dynamicznego rozwiązanie tego gdzie masz nieokreślonej liczby kolumn transpozycji do niezupełnie 3, można znaleźć ładne rozwiązanie tutaj: https://github.com/jumpstarter-io/colpivot

Powiązane problemy