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

Výběr více hodnot max() pomocí jediného příkazu SQL

Ještě jednou, pro více než jen několik "datových typů" doporučuji použít crosstab() :

SELECT * FROM crosstab(
     $$SELECT DISTINCT ON (1, 2)
              'max' AS "type", data_type, val
       FROM   tbl
       ORDER  BY 1, 2, val DESC$$

    ,$$VALUES ('Final Fantasy'), ('Quake 3'), ('World of Warcraft')$$)
AS x ("type" text, "Final Fantasy" int, "Quake 3" int, "World of Warcraft" int)

Vrátí:

type | Final Fantasy | Quake 3 | World of Warcraft
-----+---------------+---------+-------------------
max  | 500           | 1500    |    1200

Další vysvětlení základů:
PostgreSQL Crosstab Query

Dynamické řešení

Ošemetná věc je udělat to zcela dynamickým :aby to fungovalo pro

  • neznámé číslo sloupců (v tomto případě datové_typy)
  • s neznámými jmény (opět data_types)

Alespoň typ je dobře známé:integer v tomto případě.

Stručně řečeno:to není možné se současným PostgreSQL (včetně 9.3). Existují aproximace s polymorfními typy a způsoby, jak obejít omezení pomocí polí nebo typů hstore. Může to být pro vás dost dobré. Ale to přísně není možné získat výsledek s jednotlivými sloupci v jediném SQL dotazu. SQL je velmi rigidní, pokud jde o typy, a chce vědět, co očekávat.

Nicméně , lze to provést pomocí dvou dotazy. První vytvoří skutečný dotaz, který se má použít. Na základě výše uvedeného jednoduchého případu:

SELECT $f$SELECT * FROM crosstab(
     $$SELECT DISTINCT ON (1, 2)
              'max' AS "type", data_type, val
       FROM   tbl
       ORDER  BY 1, 2, val DESC$$

    ,$$VALUES ($f$     || string_agg(quote_literal(data_type), '), (') || $f$)$$)
AS x ("type" text, $f$ || string_agg(quote_ident(data_type), ' int, ') || ' int)'
FROM  (SELECT DISTINCT data_type FROM tbl) x

Tím se vygeneruje dotaz, který skutečně potřebujete. Spusťte druhý v rámci stejné transakce abyste se vyhnuli problémům se souběhem.

Všimněte si strategického použití quote_literal() a quote_ident() dezinfikovat všechny druhy nelegálních (pro sloupce) názvů a zabránit vkládání SQL .

Nenechte se zmást několika vrstvami dolarových kotací. To je nezbytné pro vytváření dynamických dotazů. Řekl jsem to co nejjednodušší.



  1. MySQL:Přidejte sloupec sekvence na základě jiného pole

  2. Přeměňte výsledek databáze na pole

  3. Statistiky tabulky GTT a SYS.WRI$_OPTSTAT_TAB_HISTORY

  4. Část 1 – Jak nainstalovat databázi SuiteCRM a Reverse Engineer