sql >> Databasteknik >  >> RDS >> PostgreSQL

Hur gör man samma aggregering på varje kolumn, utan att lista kolumnerna?

Du behöver dynamisk SQL för det, vilket innebär att du måste skapa en funktion eller köra en DO kommando. Eftersom du inte kan returnera värden direkt från den senare, en plpgsql-funktion det är:

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:

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

Returnerar:

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

Mer förklaring och länkar om dynamisk SQL och EXECUTE i den här relaterade frågan - eller ett par till här på SO, prova den här sökningen.

Mycket lik denna fråga:
postgresql - antal (inga nollvärden) av varje kolumn i en tabell

Du kan till och med försöka returnera en polymorf posttyp för att få enstaka kolumner dynamiskt, men det är ganska komplicerat och avancerat. Förmodligen för mycket ansträngning för ditt fall. Mer i detta relaterade svar.




  1. Allt du behöver veta om LIKE Operator i SQL

  2. Databasdesign för flerspråkiga applikationer

  3. MySQL - SELECT WHERE field IN (subquery) - Extremt långsam varför?

  4. Sortera efter veckodag från måndag till söndag