The following script loops over some PostgreSQL tables and grabs row counts

-- 1) Where results will go
CREATE TEMP TABLE tmp_table_stats (
  schema_name      text,
  table_name       text,
  row_count        bigint,
  lastupdated_max  timestamptz,
  count_method     text  -- 'exact' (this script) or 'estimate' (alternative below)
);

-- 2) Gather stats for all non-system tables (exact counts)
DO $$
DECLARE
  r           RECORD;
  colname     text;
  cnt         bigint;
  max_ts      timestamptz;
BEGIN
  FOR r IN
    SELECT
      n.nspname AS schema_name,
      c.relname AS table_name,
      c.oid     AS relid,
      quote_ident(n.nspname) AS qi_schema,
      quote_ident(c.relname) AS qi_table
    FROM pg_class c
    JOIN pg_namespace n ON n.oid = c.relnamespace
    WHERE c.relkind = 'r'                    -- ordinary tables
      AND n.nspname NOT IN ('pg_catalog','information_schema','pg_toast')
    ORDER BY 1, 2
  LOOP
    -- exact row count
    EXECUTE format('SELECT count(*) FROM %s.%s', r.qi_schema, r.qi_table)
      INTO cnt;

    -- find a column named lastUpdated / lastupdated (quoted vs unquoted)
    SELECT a.attname
      INTO colname
    FROM pg_attribute a
    WHERE a.attrelid = r.relid
      AND NOT a.attisdropped
      AND lower(a.attname) = 'lastupdated'
    LIMIT 1;

    IF colname IS NOT NULL THEN
      EXECUTE format('SELECT max(%s) FROM %s.%s',
                     quote_ident(colname), r.qi_schema, r.qi_table)
        INTO max_ts;
    ELSE
      max_ts := NULL;
    END IF;

    INSERT INTO tmp_table_stats(schema_name, table_name, row_count, lastupdated_max, count_method)
    VALUES (r.schema_name, r.table_name, cnt, max_ts, 'exact');
  END LOOP;
END
$$;

By Rudy