PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Żądanie zapytania transpozycji krzyżowej

Szczególna trudność polega na tym, że Twoje dane nie są gotowe do tabeli krzyżowej. Potrzebujesz danych w formacie nazwa_wiersza , kategoria , wartość . Możesz to uzyskać za pomocą UNION zapytanie:

SELECT 'metric1' AS metric, country_code, metric1 FROM tbl1
UNION ALL
SELECT 'metric2' AS metric, country_code, metric2 FROM tbl1
UNION ALL
SELECT 'metric3' AS metric, country_code, metric3 FROM tbl1
ORDER  BY 1, 2 DESC;

Ale sprytny LATERAL zapytanie wymaga tylko pojedynczego skanowania tabeli i będzie szybsze:

SELECT x.metric, t.country_code, x.val
FROM   tbl1 t
     , LATERAL (VALUES
         ('metric1', metric1)
       , ('metric2', metric2)
       , ('metric3', metric3)
       ) x(metric, val)
ORDER  BY 1, 2 DESC;

Powiązane:

Używając prostej formy crosstab() z 1 parametrem z tym zapytaniem jako danymi wejściowymi:

SELECT * FROM crosstab(
 $$SELECT x.metric, t.country_code, x.val
   FROM   tbl1 t
        , LATERAL (VALUES
            ('metric1', metric1)
          , ('metric2', metric2)
          , ('metric3', metric3)
          ) x(metric, val)
   ORDER  BY 1, 2 DESC$$
   )
AS ct (metric text, us int, uk int, fr int);

Lista nazw krajów w kolejności alfabetycznej malejącej (tak jak w demonstracji). Zakłada się również, że wszystkie metryki są zdefiniowane NOT NULL .

Jeśli jeden lub oba nie są w tym przypadku, użyj zamiast tego formularza 2-parametrowego:

Dodaj „podsumowanie”

Tj. sumy na metrykę:

SELECT * FROM crosstab(
 $$SELECT x.metric, t.country_code, x.val
   FROM  (
      TABLE tbl1
      UNION ALL
      SELECT 'zzz_total', sum(metric1)::int, sum(metric2)::int, sum(metric3)::int  -- etc.
      FROM tbl1
      ) t
        , LATERAL (VALUES
            ('metric1', metric1)
          , ('metric2', metric2)
          , ('metric3', metric3)
          ) x(metric, val)
   ORDER  BY 1, 2 DESC$$
   )
AS ct (metric text, total int, us int, uk int, fr int);

'zzz_total' to dowolna etykieta, która musi być posortowana alfabetycznie (lub potrzebna jest dwuparametrowa forma crosstab() ).

Jeśli masz dużo kolumn metryk, możesz chcieć dynamicznie skompilować ciąg zapytania. Powiązane:

Należy również pamiętać, że nadchodzący Postgres 9.5 (obecnie beta) wprowadza dedykowany Klauzula SQL dla ROLLUP .
Powiązane:




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Wiersz poleceń Windows PSQL:czy istnieje sposób na umożliwienie logowania bez hasła?

  2. Jak wysłać zapytanie do kolumny json dla pustych obiektów?

  3. Pliki ewolucji Playframework kompatybilne zarówno z postgresem, jak i h2

  4. Korzystanie z funkcji korelacji PostgreSQL

  5. Ograniczenie unikatowej wartości w wielu kolumnach