sql >> Database >  >> RDS >> PostgreSQL

Hoe voer je dezelfde aggregatie uit op elke kolom, zonder de kolommen op te sommen?

Je hebt dynamische SQL nodig daarvoor, wat betekent dat je een functie moet maken of een DO . moet uitvoeren opdracht. Aangezien u geen waarden rechtstreeks van de laatste kunt retourneren, is een plpgsql-functie het is:

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

Bel:

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

Retourneren:

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

Meer uitleg en links over dynamische SQL en EXECUTE in deze gerelateerde vraag - of een paar meer hier op SO, probeer deze zoekopdracht.

Zeer vergelijkbaar met deze vraag:
postgresql - telling (geen null-waarden) van elke kolom in een tabel

Je zou zelfs kunnen proberen een polymorf recordtype te retourneren om dynamisch enkele kolommen te krijgen, maar dat is nogal complex en geavanceerd. Waarschijnlijk teveel moeite voor jouw geval. Meer in dit gerelateerde antwoord.




  1. Hoe gebruik ik de CONCAT-functie in SQL Server 2008 R2?

  2. Draait Oracle de transactie terug bij een fout?

  3. Hoe werk ik met zeer nauwkeurige decimalen in PHP

  4. Geïndexeerde weergaven en statistieken