sql >> Databáze >  >> RDS >> PostgreSQL

Požadavek na křížovou transpozici dotazu

Zvláštní problém spočívá v tom, že vaše data nejsou připravena pro křížovou tabulku. Potřebujete údaje ve tvaru název_řádku , kategorie , hodnota . Můžete to získat pomocí UNION dotaz:

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 chytrý LATERAL dotaz potřebuje pouze prohledání jedné tabulky a bude rychlejší:

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;

Související:

Pomocí jednoduchého tvaru crosstab() s 1 parametrem s tímto dotazem jako vstupem:

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

Uveďte názvy zemí v abecedním sestupném pořadí (jako ve vaší ukázce). To také předpokládá, že všechny metriky jsou definovány NOT NULL .

Pokud jeden nebo oba neplatí, použijte místo toho formulář se 2 parametry:

Přidat souhrn

Tj. součty za metriku:

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' je libovolný štítek, který musí seřadit na posledním místě podle abecedy (nebo potřebujete 2parametrovou formu crosstab() ).

Pokud máte spoustu sloupců metrik, možná budete chtít vytvořit řetězec dotazu dynamicky. Související:

Všimněte si také, že nadcházející Postgres 9.5 (aktuálně beta) zavádí vyhrazený klauzule SQL pro ROLLUP .
Související:




  1. Změňte tabulku MySQL a přidejte komentáře ke sloupcům

  2. Nelze vytvořit ovladač z NHibernate.Driver.OracleDataClientDriver

  3. Jak zašifrovat rozdělenou databázi v Accessu 2016

  4. SQL Server, Jak nastavit automatický přírůstek po vytvoření tabulky bez ztráty dat?