Search code examples
sqlpostgresqlpgadmin

Query to find and join all tables in a postgres database


I have a unique situation where all tables in a database will have the same columns and data types, yet must be kept as separate tables.

I'd like to write a query that can find all of those tables and join them, preferably with one column that identifies the source table. I need it to find all the tables, rather than specify them, as they will change over time and re-writing this query is likely to be a nuisance.

Is this possible?

To illustrate:

database: all_data

table: red
columns: date text, value numeric, notes text

table: green
columns: date text, value numeric, notes text

... etc etc

The output would be:

source:   date:    value:    notes:
red       9/24     12        good
red       9/23     1         review
green     9/21     -1        fail
green     9/10     100       excellent

Solution

  • You can make a Dynamic query, like this:

    You have to filter using the correct table_schema.

    SELECT 
          regexp_replace(string_agg('SELECT ''' || table_name || ''' AS source, date, value, notes FROM ' || table_name || ' UNION ALL ', ' '), ' UNION ALL $', ';') AS "query"
    FROM information_schema.tables
    WHERE table_schema = 'public';
    

    Example output:

    SELECT 'red' AS source, date, value, notes FROM red 
    
    UNION ALL  
    
    SELECT 'green' AS source, date, value, notes FROM green;
    

    Creating a PL/pgSQL function (It is an example, maybe you can improve it):

    CREATE FUNCTION getAllTablesRows() RETURNS TABLE(source text, date text, value numeric, notes text) AS
    $$
    
    DECLARE
    
        cursorTables CURSOR FOR SELECT table_name FROM information_schema.tables WHERE table_schema = 'public';
    
    BEGIN
    
        FOR tableName IN cursorTables LOOP
            RETURN QUERY EXECUTE format('SELECT %L::text AS source, date, value, notes FROM %I', tableName.table_name, tableName.table_name);
        END LOOP;
    
    END;
    
    $$ LANGUAGE 'plpgsql';
    

    Calling it:

    SELECT * FROM getAllTablesRows();