<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Information_schema on Postgres Scripts</title><link>https://www.postgresscripts.com/tags/information_schema/</link><description>Recent content in Information_schema on Postgres Scripts</description><generator>Hugo -- gohugo.io</generator><language>en</language><copyright>PostgresScripts.com</copyright><lastBuildDate>Thu, 09 Apr 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://www.postgresscripts.com/tags/information_schema/index.xml" rel="self" type="application/rss+xml"/><item><title>List PostgreSQL Partitioned Tables with SQL</title><link>https://www.postgresscripts.com/post/list-postgresql-partitioned-tables/</link><pubDate>Thu, 09 Apr 2026 00:00:00 +0000</pubDate><guid>https://www.postgresscripts.com/post/list-postgresql-partitioned-tables/</guid><description>
&lt;h2 id="how-to-list-postgresql-partitioned-tables"&gt;How to List PostgreSQL Partitioned Tables&lt;/h2&gt;
&lt;p&gt;PostgreSQL table partitioning splits a large table into smaller physical pieces called child partitions. This improves query performance and simplifies data lifecycle management. But as a DBA, you need a quick way to see which tables in your database use partitioning — and which do not.&lt;/p&gt;
&lt;p&gt;This SQL query reads directly from the PostgreSQL system catalogs to list every table in your database, labeling each as a partitioned table or an ordinary table, while excluding system schemas and child partition tables.&lt;/p&gt;</description></item><item><title>Find PostgreSQL Tables Without a Primary Key</title><link>https://www.postgresscripts.com/post/find-postgresql-tables-without-primary-key/</link><pubDate>Wed, 08 Apr 2026 00:00:00 +0000</pubDate><guid>https://www.postgresscripts.com/post/find-postgresql-tables-without-primary-key/</guid><description>
&lt;h2 id="how-to-find-postgresql-tables-without-a-primary-key"&gt;How to Find PostgreSQL Tables Without a Primary Key&lt;/h2&gt;
&lt;p&gt;A missing primary key is one of the most common and damaging database design oversights. Without a primary key, PostgreSQL has no reliable way to uniquely identify a row. This causes problems with logical replication, ORM frameworks, and application-level updates or deletes that may silently affect the wrong rows.&lt;/p&gt;
&lt;p&gt;This SQL query scans &lt;code&gt;information_schema&lt;/code&gt; to find every user table in your database that has no primary key or unique key constraint. Running it regularly is a simple way to catch schema problems before they reach production.&lt;/p&gt;</description></item><item><title>List All Views in a PostgreSQL Database with SQL</title><link>https://www.postgresscripts.com/post/list-postgresql-database-views/</link><pubDate>Tue, 07 Apr 2026 00:00:00 +0000</pubDate><guid>https://www.postgresscripts.com/post/list-postgresql-database-views/</guid><description>
&lt;h2 id="how-to-list-all-views-in-a-postgresql-database"&gt;How to List All Views in a PostgreSQL Database&lt;/h2&gt;
&lt;p&gt;Views are saved SQL queries stored in the database. A production database can accumulate dozens or hundreds of views over time — many created by developers, some by tools, and some that are no longer used. Knowing what views exist, which schema they belong to, and what they actually do is essential for documentation, auditing, and cleanup.&lt;/p&gt;
&lt;p&gt;This SQL script queries &lt;code&gt;information_schema.views&lt;/code&gt; to return every view in the current database, along with its schema and full SQL definition.&lt;/p&gt;</description></item><item><title>List PostgreSQL Enum Types and Their Values with SQL</title><link>https://www.postgresscripts.com/post/list-postgresql-enum-types/</link><pubDate>Mon, 06 Apr 2026 00:00:00 +0000</pubDate><guid>https://www.postgresscripts.com/post/list-postgresql-enum-types/</guid><description>
&lt;h2 id="how-to-list-all-enum-types-in-a-postgresql-database"&gt;How to List All Enum Types in a PostgreSQL Database&lt;/h2&gt;
&lt;p&gt;PostgreSQL supports user-defined enum types — a fixed ordered set of string values stored efficiently as integers. Enums are common in application schemas for columns like &lt;code&gt;status&lt;/code&gt;, &lt;code&gt;role&lt;/code&gt;, or &lt;code&gt;priority&lt;/code&gt;. Once created, their allowed values are managed in the database catalog, not in application code.&lt;/p&gt;
&lt;p&gt;Over time, a database can accumulate many enum types, some with values that no longer match what the application uses. This SQL script queries &lt;code&gt;pg_type&lt;/code&gt; and &lt;code&gt;pg_enum&lt;/code&gt; to list every enum type in the current database along with all of its allowed values.&lt;/p&gt;</description></item><item><title>List Foreign Key Constraints in PostgreSQL</title><link>https://www.postgresscripts.com/post/list-foreign-key-constraints-in-postgresql/</link><pubDate>Sun, 05 Apr 2026 00:00:00 +0000</pubDate><guid>https://www.postgresscripts.com/post/list-foreign-key-constraints-in-postgresql/</guid><description>
&lt;h2 id="list-foreign-key-constraints-in-postgresql"&gt;List Foreign Key Constraints in PostgreSQL&lt;/h2&gt;
&lt;p&gt;Foreign key constraints enforce referential integrity between tables. They guarantee that a value in one table's column always has a matching row in another table. Knowing which foreign keys exist — and how they are defined — is essential before dropping tables, renaming columns, or loading large datasets.&lt;/p&gt;
&lt;p&gt;This SQL query lists every foreign key in the public schema, showing the table that owns the constraint, the constraint name, and the full constraint definition including which columns it spans and which table it references.&lt;/p&gt;</description></item><item><title>List PostgreSQL Object Comments with SQL</title><link>https://www.postgresscripts.com/post/list-postgresql-object-comments/</link><pubDate>Sat, 04 Apr 2026 00:00:00 +0000</pubDate><guid>https://www.postgresscripts.com/post/list-postgresql-object-comments/</guid><description>
&lt;h2 id="list-postgresql-object-comments-with-sql"&gt;List PostgreSQL Object Comments with SQL&lt;/h2&gt;
&lt;p&gt;PostgreSQL allows you to attach plain-text comments to tables, columns, indexes, functions, and other database objects using the &lt;code&gt;COMMENT ON&lt;/code&gt; command. These comments are stored in the system catalog and are visible in psql, pgAdmin, and any tool that reads &lt;code&gt;pg_description&lt;/code&gt;. They are one of the most underused features for keeping a schema self-documenting.&lt;/p&gt;
&lt;p&gt;This SQL query lists comments on every column across all tables in your database, showing the schema, table name, column name, and the comment text. It is useful for auditing schema documentation, onboarding new team members, and verifying that comments are in place before a schema handover.&lt;/p&gt;</description></item><item><title>Detect Soft Delete Patterns in PostgreSQL</title><link>https://www.postgresscripts.com/post/detect-soft-delete-patterns-in-postgresql/</link><pubDate>Fri, 03 Apr 2026 00:00:00 +0000</pubDate><guid>https://www.postgresscripts.com/post/detect-soft-delete-patterns-in-postgresql/</guid><description>
&lt;h2 id="detecting-soft-delete-patterns-in-postgresql"&gt;Detecting Soft Delete Patterns in PostgreSQL&lt;/h2&gt;
&lt;p&gt;Soft deletes are a common application pattern. Instead of removing a row with a &lt;code&gt;DELETE&lt;/code&gt; statement, the application marks it as deleted by setting a column — typically &lt;code&gt;deleted_at&lt;/code&gt; — to a non-null timestamp. The row stays in the table forever. The application simply filters it out with a &lt;code&gt;WHERE deleted_at IS NULL&lt;/code&gt; clause.&lt;/p&gt;
&lt;p&gt;This pattern is useful for audit trails, undo functionality, and referential integrity. It is also a significant source of problems for PostgreSQL DBAs who do not know it is in use.&lt;/p&gt;</description></item><item><title>List PostgreSQL Tables by Size with SQL</title><link>https://www.postgresscripts.com/post/list-postgresql-tables-by-size-with-sql/</link><pubDate>Sun, 15 Mar 2026 00:00:00 +0000</pubDate><guid>https://www.postgresscripts.com/post/list-postgresql-tables-by-size-with-sql/</guid><description>
&lt;h2 id="list-postgresql-tables-by-size-with-sql"&gt;List PostgreSQL Tables by Size with SQL&lt;/h2&gt;
&lt;p&gt;This PostgreSQL query lists all tables in the current database sorted by their total size, largest first. It uses &lt;code&gt;pg_total_relation_size()&lt;/code&gt; to include the table data, indexes, TOAST storage, and free space map in the size calculation.&lt;/p&gt;
&lt;h2 id="purpose-and-overview"&gt;Purpose and Overview&lt;/h2&gt;
&lt;p&gt;Disk space pressure is a common operational concern in any growing database. Knowing which tables consume the most space allows administrators to prioritise archiving, partitioning, or compression efforts. It also helps explain sudden disk growth when a particular table has expanded unexpectedly.&lt;/p&gt;</description></item><item><title>PostgreSQL Table Row Count Estimates with SQL</title><link>https://www.postgresscripts.com/post/postgresql-table-row-count-estimates-with-sql/</link><pubDate>Sat, 14 Mar 2026 00:00:00 +0000</pubDate><guid>https://www.postgresscripts.com/post/postgresql-table-row-count-estimates-with-sql/</guid><description>
&lt;h2 id="postgresql-table-row-count-estimates-with-sql"&gt;PostgreSQL Table Row Count Estimates with SQL&lt;/h2&gt;
&lt;p&gt;This PostgreSQL query returns estimated row counts for all user tables, sorted by the largest tables first. It reads from the statistics collector rather than scanning the tables, making it near-instant even on tables with billions of rows.&lt;/p&gt;
&lt;h2 id="purpose-and-overview"&gt;Purpose and Overview&lt;/h2&gt;
&lt;p&gt;Counting rows with &lt;code&gt;SELECT COUNT(*) FROM table&lt;/code&gt; requires a full sequential scan of the table — on large tables this can run for minutes and generate significant I/O load. PostgreSQL's statistics collector maintains a continuously updated row estimate for every table in &lt;code&gt;pg_stat_user_tables&lt;/code&gt;. This estimate is fast to read and accurate enough for most operational purposes.&lt;/p&gt;</description></item><item><title>Identify Underutilized PostgreSQL Columns for Optimization</title><link>https://www.postgresscripts.com/post/find-underutilized-columns-and-optimize-your-postgresql-database-schema/</link><pubDate>Wed, 03 Apr 2024 00:00:00 +0000</pubDate><guid>https://www.postgresscripts.com/post/find-underutilized-columns-and-optimize-your-postgresql-database-schema/</guid><description>
&lt;h2 id="identifying-underutilized-columns-in-your-postgresql-database"&gt;Identifying Underutilized Columns in Your PostgreSQL Database&lt;/h2&gt;
&lt;p&gt;Keeping your PostgreSQL database clean and efficient is crucial for optimal performance. One way to achieve this is by identifying and potentially removing &amp;quot;useless&amp;quot; columns – those that hold minimal or redundant data. This article explores a PostgreSQL code snippet designed to unearth such columns, helping you optimize your database schema.&lt;/p&gt;
&lt;script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-1012089347386563"
crossorigin="anonymous"&gt;&lt;/script&gt;
&lt;ins class="adsbygoogle"
style="display:block"
data-ad-client="ca-pub-1012089347386563"
data-ad-slot="7945792173"
data-ad-format="auto"
data-full-width-responsive="true"&gt;&lt;/ins&gt;
&lt;script&gt;
(adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;h2 id="sample-code-from-command-line"&gt;Sample Code from Command Line&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;SELECT
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt; nspname,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt; relname,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt; attname,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt; typname,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt; (stanullfrac*100)::int AS null_percent,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt; case
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt; when stadistinct &amp;gt;= 0
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt; then stadistinct
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt; else
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt; abs(stadistinct)*reltuples
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt; end AS &amp;#34;distinct&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt; case 1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt; when stakind1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt; then stavalues1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt; when stakind2
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt; then stavalues2
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt; end AS &amp;#34;values&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt;FROM
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt; pg_class c
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt;JOIN
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt; pg_namespace ns
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt;ON
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt; (ns.oid=relnamespace)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;JOIN
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt; pg_attribute
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt;ON
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt; (c.oid=attrelid)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt;JOIN
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt; pg_type t
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt;ON
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt; (t.oid=atttypid)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt;JOIN
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt; pg_statistic
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt;ON
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;36&lt;/span&gt;&lt;span class="cl"&gt; (c.oid=starelid AND staattnum=attnum)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;37&lt;/span&gt;&lt;span class="cl"&gt;WHERE
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;38&lt;/span&gt;&lt;span class="cl"&gt; nspname NOT LIKE E&amp;#39;pg\\_%&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;39&lt;/span&gt;&lt;span class="cl"&gt; AND
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;40&lt;/span&gt;&lt;span class="cl"&gt; nspname != &amp;#39;information_schema&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;41&lt;/span&gt;&lt;span class="cl"&gt; AND
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;42&lt;/span&gt;&lt;span class="cl"&gt; relkind = &amp;#39;r&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;43&lt;/span&gt;&lt;span class="cl"&gt; AND
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;44&lt;/span&gt;&lt;span class="cl"&gt; NOT attisdropped
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;45&lt;/span&gt;&lt;span class="cl"&gt; AND
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;46&lt;/span&gt;&lt;span class="cl"&gt; attstattarget != 0
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;47&lt;/span&gt;&lt;span class="cl"&gt; AND
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;48&lt;/span&gt;&lt;span class="cl"&gt; reltuples &amp;gt;= 100
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;49&lt;/span&gt;&lt;span class="cl"&gt; AND
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;50&lt;/span&gt;&lt;span class="cl"&gt; stadistinct BETWEEN 0 AND 1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;51&lt;/span&gt;&lt;span class="cl"&gt;ORDER BY
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;52&lt;/span&gt;&lt;span class="cl"&gt; nspname,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;53&lt;/span&gt;&lt;span class="cl"&gt; relname,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;54&lt;/span&gt;&lt;span class="cl"&gt; attname;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Notes:&lt;/strong&gt; Finds useless PostgreSQL columns containing only a single value eg. all NULLs or a redundant non-distinguishing field. Only returns columns with over 100 rows. Tested on PostgreSQL 8.4, 9.x, 10.x, 11.x, 12.x, 13.0&lt;/p&gt;</description></item><item><title>PostgreSQL query to find columns containing only NULL values</title><link>https://www.postgresscripts.com/post/identify-columns-containing-null-values-in-postgresql/</link><pubDate>Sun, 24 Mar 2024 00:00:00 +0000</pubDate><guid>https://www.postgresscripts.com/post/identify-columns-containing-null-values-in-postgresql/</guid><description>
&lt;h2 id="identifying-null-only-columns-in-postgresql"&gt;Identifying Null-Only Columns in PostgreSQL&lt;/h2&gt;
&lt;p&gt;This article explores a valuable PostgreSQL query for database administrators. It helps identify columns within your database tables that exclusively contain NULL values. Uncovering these &amp;quot;null-only&amp;quot; columns can be a key step in optimizing storage usage and streamlining your database schema design.&lt;/p&gt;
&lt;script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-1012089347386563"
crossorigin="anonymous"&gt;&lt;/script&gt;
&lt;ins class="adsbygoogle"
style="display:block"
data-ad-client="ca-pub-1012089347386563"
data-ad-slot="7945792173"
data-ad-format="auto"
data-full-width-responsive="true"&gt;&lt;/ins&gt;
&lt;script&gt;
(adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;h2 id="sample-code-from-command-line"&gt;Sample Code from Command Line&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 1&lt;/span&gt;&lt;span class="cl"&gt;SELECT
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 2&lt;/span&gt;&lt;span class="cl"&gt; nspname,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 3&lt;/span&gt;&lt;span class="cl"&gt; relname,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 4&lt;/span&gt;&lt;span class="cl"&gt; attname,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 5&lt;/span&gt;&lt;span class="cl"&gt; typname,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 6&lt;/span&gt;&lt;span class="cl"&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 7&lt;/span&gt;&lt;span class="cl"&gt; stanullfrac*100
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 8&lt;/span&gt;&lt;span class="cl"&gt; )
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt; 9&lt;/span&gt;&lt;span class="cl"&gt; ::int AS null_percent
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;10&lt;/span&gt;&lt;span class="cl"&gt;FROM
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;11&lt;/span&gt;&lt;span class="cl"&gt; pg_class c
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;12&lt;/span&gt;&lt;span class="cl"&gt; JOIN
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;13&lt;/span&gt;&lt;span class="cl"&gt; pg_namespace ns
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;14&lt;/span&gt;&lt;span class="cl"&gt; ON (ns.oid = relnamespace)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;15&lt;/span&gt;&lt;span class="cl"&gt; JOIN
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;16&lt;/span&gt;&lt;span class="cl"&gt; pg_attribute
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;17&lt;/span&gt;&lt;span class="cl"&gt; ON (c.oid = attrelid)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;18&lt;/span&gt;&lt;span class="cl"&gt; JOIN
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;19&lt;/span&gt;&lt;span class="cl"&gt; pg_type t
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;20&lt;/span&gt;&lt;span class="cl"&gt; ON (t.oid = atttypid)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;21&lt;/span&gt;&lt;span class="cl"&gt; JOIN
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;22&lt;/span&gt;&lt;span class="cl"&gt; pg_statistic
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;23&lt;/span&gt;&lt;span class="cl"&gt; ON (c.oid = starelid
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;24&lt;/span&gt;&lt;span class="cl"&gt; AND staattnum = attnum)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;25&lt;/span&gt;&lt;span class="cl"&gt;WHERE
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;26&lt;/span&gt;&lt;span class="cl"&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;27&lt;/span&gt;&lt;span class="cl"&gt; stanullfrac*100
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;28&lt;/span&gt;&lt;span class="cl"&gt; )
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;29&lt;/span&gt;&lt;span class="cl"&gt; ::int = 100
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;30&lt;/span&gt;&lt;span class="cl"&gt; AND nspname NOT LIKE E&amp;#39;pg\\_%&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;31&lt;/span&gt;&lt;span class="cl"&gt; AND nspname != &amp;#39;information_schema&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;32&lt;/span&gt;&lt;span class="cl"&gt; AND relkind = &amp;#39;r&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;33&lt;/span&gt;&lt;span class="cl"&gt; AND NOT attisdropped
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;34&lt;/span&gt;&lt;span class="cl"&gt; AND attstattarget != 0 -- AND
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;35&lt;/span&gt;&lt;span class="cl"&gt; --reltuples &amp;gt;= 100
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;36&lt;/span&gt;&lt;span class="cl"&gt;ORDER BY
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;37&lt;/span&gt;&lt;span class="cl"&gt; nspname,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;38&lt;/span&gt;&lt;span class="cl"&gt; relname,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;39&lt;/span&gt;&lt;span class="cl"&gt; attname;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Notes:&lt;/strong&gt; Finds PostgreSQL columns that contain only NULLs. Tested on PostgreSQL 8.4, 9.x, 10.x, 11.x, 12.x, 13.0.&lt;/p&gt;</description></item></channel></rss>