PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Wie kann man dieselbe Aggregation für jede Spalte durchführen, ohne die Spalten aufzulisten?

Sie benötigen dynamisches SQL dafür müssen Sie eine Funktion erstellen oder ein DO ausführen Befehl. Da Sie von letzterem keine Werte direkt zurückgeben können, ist eine plpgsql-Funktion erforderlich es ist:

CREATE OR REPLACE function f_count_all(_tbl text
                           , OUT columns text[], OUT counts bigint[])
  RETURNS record LANGUAGE plpgsql AS
$func$
BEGIN

EXECUTE (
    SELECT 'SELECT
     ARRAY[' || string_agg('''' || quote_ident(attname) || '''', ', ') || '], 
     ARRAY[' || string_agg('count(' || quote_ident(attname) || ')', ', ') || ']
    FROM ' || _tbl
    FROM   pg_attribute
    WHERE  attrelid = _tbl::regclass
    AND    attnum  >= 1           -- exclude tableoid & friends (neg. attnum)
    AND    attisdropped is FALSE  -- exclude deleted columns
    GROUP  BY attrelid
    )
INTO columns, counts;

END
$func$;

Aufruf:

SELECT * FROM f_count_all('myschema.mytable');

Rückgabe:

columns       | counts
--------------+--------
{c1, c2, c3,} | {17 1,0}

Weitere Erklärungen und Links zu dynamischem SQL und EXECUTE in dieser verwandten Frage - oder ein paar mehr hier auf SO, versuchen Sie diese Suche.

Dieser Frage sehr ähnlich:
postgresql - Anzahl (keine Nullwerte) jeder Spalte in einer Tabelle

Sie könnten sogar versuchen, einen polymorphen Datensatztyp zurückzugeben, um einzelne Spalten dynamisch zu erhalten, aber das ist ziemlich komplex und fortgeschritten. Wahrscheinlich zu viel Aufwand für deinen Fall. Mehr in dieser verwandten Antwort.