Get exact row counts per table in a given schema — PostgreSQL primary, with notes for other engines. Two-column result: table_name, row_count.
Scanned 9/2/2026
Install to Claude Code
npx -y skills add CarlosCaPe/octorato --skill schema-row-counts --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Schema Row Counts?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/carloscape-schema-row-counts)More formats (shields.io, HTML) on the badges page.
---
name: schema-row-counts
description: "Get exact row counts per table in a given schema — PostgreSQL primary, with notes for other engines. Two-column result: table_name, row_count."
metadata:
type: skill
---
# schema-row-counts
Returns a two-column table (`table_name`, `row_count`) for every BASE TABLE in a schema.
## PostgreSQL — exact count (any schema)
```sql
SELECT
table_name,
(xpath('/row/cnt/text()',
query_to_xml(format('SELECT COUNT(*) AS cnt FROM %I.%I', table_schema, table_name),
false, true, ''))
)[1]::text::int AS row_count
FROM information_schema.tables
WHERE table_schema = '<schema>' -- replace with target schema
AND table_type = 'BASE TABLE'
ORDER BY row_count DESC, table_name;
```
**Replace `<schema>`** with the target schema name (e.g., `payer`, `eligibility`, `public`).
## PostgreSQL — fast approximate (uses pg_stat, no full scan)
Use when tables are large and exact counts are not required (e.g., dashboards, health checks):
```sql
SELECT
relname AS table_name,
n_live_tup AS row_count
FROM pg_stat_user_tables
WHERE schemaname = '<schema>'
ORDER BY n_live_tup DESC, relname;
```
Stats lag behind until `ANALYZE` runs. Good for ballpark; not for audits.
## How to run (local Docker setup — newum_db pattern)
```powershell
# One-liner: replace payer with target schema
docker compose exec postgres psql -U $env:NEWUM_LOCAL_USER -d newum -c `
"SELECT table_name, (xpath('/row/cnt/text()', query_to_xml(format('SELECT COUNT(*) AS cnt FROM payer.%I', table_name), false, true, '')))[1]::text::int AS row_count FROM information_schema.tables WHERE table_schema = 'payer' AND table_type = 'BASE TABLE' ORDER BY row_count DESC, table_name;"
```
## How to run (via QueryMaster)
```bash
qm -e postgresql -c <conn> "SELECT table_name, ... WHERE table_schema = '<schema>' ..." --execute
```
## MS-SQL equivalent
```sql
SELECT
t.name AS table_name,
p.rows AS row_count
FROM sys.tables t
JOIN sys.partitions p ON p.object_id = t.object_id
AND p.index_id IN (0, 1)
WHERE SCHEMA_NAME(t.schema_id) = '<schema>'
ORDER BY p.rows DESC, t.name;
```
## Databricks / Spark SQL equivalent
```sql
SHOW TABLES IN <schema>;
-- then per table:
SELECT COUNT(*) FROM <schema>.<table>;
-- or loop via notebook:
-- %python
-- for t in spark.catalog.listTables("<schema>"):
-- print(t.name, spark.table(f"<schema>.{t.name}").count())
```
## Lessons Learned
- 2026-05-15 (newUM/OncoHealth): Applied to `payer` schema post-seed validation. 30 rows in `payer`, 0 in all others (benefit_package, business_grain, business_grouping, employer_group, payer_organization_link). Confirmed seed ran clean.
- The `xpath/query_to_xml` trick is the canonical PostgreSQL pattern for dynamic per-table counts without PL/pgSQL or superuser permissions.
- `pg_stat_user_tables` is faster but requires a recent `ANALYZE` — safe for monitoring, not for audit assertions.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!