sql >> Database teknologi >  >> RDS >> PostgreSQL

Hvordan udfører man den samme aggregering på hver kolonne uden at angive kolonnerne?

Du skal bruge dynamisk SQL for det, hvilket betyder, at du skal oprette en funktion eller køre en DO kommando. Da du ikke kan returnere værdier direkte fra sidstnævnte, er en plpgsql-funktion det er:

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

Ring til:

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

Returnerer:

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

Flere forklaringer og links om dynamisk SQL og EXECUTE i dette relaterede spørgsmål - eller et par mere her på SO, prøv denne serach.

Meget lig dette spørgsmål:
postgresql - antal (ingen nulværdier) af hver kolonne i en tabel

Du kan endda prøve at returnere en polymorf posttype for at få enkelte kolonner dynamisk, men det er ret komplekst og avanceret. Sandsynligvis for meget indsats for din sag. Mere i dette relaterede svar.




  1. Returner den første mandag i hver måned i SQLite

  2. SQLite - Opdater data

  3. NUMTOYMINTERVAL() Funktion i Oracle

  4. Opdater en kolonne i MySQL