List foreign keys in SQL Server - 7 useful SQL queries

This is a collection of queries for SQL Server system catalog (data dictionary) that help you find information about foreign keys. If you are interested in schema and metadata analysis have a look at:

Basic queries

1. Foreign keys: row per column

One row represents one foreign key column. If foreign key consists of multiple columns (composite key), each column appears separately.

select schema_name(fk_tab.schema_id) + '.' + fk_tab.name as foreign_table,
    '>-' as rel,
    schema_name(pk_tab.schema_id) + '.' + pk_tab.name as primary_table,
    fk_cols.constraint_column_id as no, 
    fk_col.name as fk_column_name,
    ' = ' as [join],
    pk_col.name as pk_column_name,
    fk.name as fk_constraint_name
from sys.foreign_keys fk
    inner join sys.tables fk_tab
        on fk_tab.object_id = fk.parent_object_id
    inner join sys.tables pk_tab
        on pk_tab.object_id = fk.referenced_object_id
    inner join sys.foreign_key_columns fk_cols
        on fk_cols.constraint_object_id = fk.object_id
    inner join sys.columns fk_col
        on fk_col.column_id = fk_cols.parent_column_id
        and fk_col.object_id = fk_tab.object_id
    inner join sys.columns pk_col
        on pk_col.column_id = fk_cols.referenced_column_id
        and pk_col.object_id = pk_tab.object_id
order by schema_name(fk_tab.schema_id) + '.' + fk_tab.name,
    schema_name(pk_tab.schema_id) + '.' + pk_tab.name, 
    fk_cols.constraint_column_id

Sample results:

Columns:

  • foreign_table - foreign table name with schema name
  • rel - relationship symbol implicating direction
  • primary_table - primary (referenced) table name with schema name
  • no - id of the column in key. Single column keys always have 1, composite keys have 1, 2, ... n for each column of the key
  • fk_column_name - foreign table column
  • join - "=" symbol indicating join operation for pair of columns
  • pk_column_name - primary (referenced) table column
  • fk_constraint_name - foreign key constraint name

2. Foreign keys: row per key

One row represents one foreign key. If foreign key consists of multiple columns (composite key) it is still represented as one row.

select schema_name(fk_tab.schema_id) + '.' + fk_tab.name as foreign_table,
    '>-' as rel,
    schema_name(pk_tab.schema_id) + '.' + pk_tab.name as primary_table,
    substring(column_names, 1, len(column_names)-1) as [fk_columns],
    fk.name as fk_constraint_name
from sys.foreign_keys fk
    inner join sys.tables fk_tab
        on fk_tab.object_id = fk.parent_object_id
    inner join sys.tables pk_tab
        on pk_tab.object_id = fk.referenced_object_id
    cross apply (select col.[name] + ', '
                    from sys.foreign_key_columns fk_c
                        inner join sys.columns col
                            on fk_c.parent_object_id = col.object_id
                            and fk_c.parent_column_id = col.column_id
                    where fk_c.parent_object_id = fk_tab.object_id
                      and fk_c.constraint_object_id = fk.object_id
                            order by col.column_id
                            for xml path ('') ) D (column_names)
order by schema_name(fk_tab.schema_id) + '.' + fk_tab.name,
    schema_name(pk_tab.schema_id) + '.' + pk_tab.name

Sample results:

Columns:

  • foreign_table - foreign table name with schema name
  • rel - relationship symbol implicating direction
  • primary_table - primary (referenced) table name with schema name
  • fk_columns - list of FK column names, separated with ","
  • fk_constraint_name - foreign key constraint name

Visualize foreign keys

Listing foreign keys is very useful, but it's also really beneficial to visualize foreign keys with ER diagrams (ERDs). Dataedo allows you to import schema from your database, describe each field and visualize quickly with several small, manageable diagrams.

Image title

Then, finally, you can share complete documentation, with diagrams and data dictionary in HTML, PDF or on prem web portal.

Image title

Try it for free now

More queries

3. All columns and their FKs (if present)

Query below returns all columns from all tables in a database with a foreign key reference if column has one.

select schema_name(tab.schema_id) + '.' + tab.name as [table],
    col.column_id,
    col.name as column_name,
    case when fk.object_id is not null then '>-' else null end as rel,
    schema_name(pk_tab.schema_id) + '.' + pk_tab.name as primary_table,
    pk_col.name as pk_column_name,
    fk_cols.constraint_column_id as no,
    fk.name as fk_constraint_name
from sys.tables tab
    inner join sys.columns col 
        on col.object_id = tab.object_id
    left outer join sys.foreign_key_columns fk_cols
        on fk_cols.parent_object_id = tab.object_id
        and fk_cols.parent_column_id = col.column_id
    left outer join sys.foreign_keys fk
        on fk.object_id = fk_cols.constraint_object_id
    left outer join sys.tables pk_tab
        on pk_tab.object_id = fk_cols.referenced_object_id
    left outer join sys.columns pk_col
        on pk_col.column_id = fk_cols.referenced_column_id
        and pk_col.object_id = fk_cols.referenced_object_id
order by schema_name(tab.schema_id) + '.' + tab.name,
    col.column_id

Sample results:

Columns:

  • table - table in a database with schema name
  • column_id - number of column in a database
  • column_name - column name
  • rel - relationship symbol ('>-') indicating foreign key and direction
  • primary_table - referenced table
  • pk_column_name - referenced column
  • no - column id in a key constraint
  • fk_constraint_name - foreign key constraint name

4. All tables referenced by specific table

Query below lists all tables referenced with foreign key by specific table.

Please note: There can be more tables with the same name. If that's the case, uncomment where clause and provide schema name.

select distinct 
    schema_name(fk_tab.schema_id) + '.' + fk_tab.name as foreign_table,
    '>-' as rel,
    schema_name(pk_tab.schema_id) + '.' + pk_tab.name as primary_table
from sys.foreign_keys fk
    inner join sys.tables fk_tab
        on fk_tab.object_id = fk.parent_object_id
    inner join sys.tables pk_tab
        on pk_tab.object_id = fk.referenced_object_id
where fk_tab.[name] = 'Your table' -- enter table name here
--  and schema_name(fk_tab.schema_id) = 'Your table schema name'
order by schema_name(fk_tab.schema_id) + '.' + fk_tab.name,
    schema_name(pk_tab.schema_id) + '.' + pk_tab.name

Sample results:

Columns:

  • foreign_table - foreign table name with schema name - the table you provided as a parameter
  • foreign_table - relationship symbol implicating FK and direction
  • primary_table - primary (referenced) tables names with schema name - the tables you are looking for

5. All tables referencing specific table

Query below lists all tables that reference specific table with foreign keys.

Please note: There can be more tables with the same name. If that's the case, uncomment where clause and provide schema name.

select distinct 
    schema_name(fk_tab.schema_id) + '.' + fk_tab.name as foreign_table,
    '>-' as rel,
    schema_name(pk_tab.schema_id) + '.' + pk_tab.name as primary_table
from sys.foreign_keys fk
    inner join sys.tables fk_tab
        on fk_tab.object_id = fk.parent_object_id
    inner join sys.tables pk_tab
        on pk_tab.object_id = fk.referenced_object_id
where pk_tab.[name] = 'Your table' -- enter table name here
--  and schema_name(pk_tab.schema_id) = 'Your table schema name'
order by schema_name(fk_tab.schema_id) + '.' + fk_tab.name,
    schema_name(pk_tab.schema_id) + '.' + pk_tab.name

Sample results:

Columns:

  • foreign_table - foreign tables schemas and names - the table you are looking for
  • foreign_table - relationship symbol implicating FK and direction
  • primary_table - primary (referenced) tables names with schema name - the table you provided as a parameter

What if foreign key constraints are note defined in your database?

Many databases, even major applications from Microsoft, Oracle or SAP do not have foreign key constraints in their schema. That means you can't discover relationships with queries in this article. There are many reasons for why that is.

What if your database looked more like this?

Image title

Well, in that case you can always document foreign keys in your database with Dataedo. Simply connect to your database, import schema to local repository and define relationships (but also, keys, descriptions, aliases, and more). That will give you (and everyone using or designing the database) reference documentation, and you will be able to create ER diagrams, too.

Image title

Image title

Try it for free now

Statistical queries

6. Most referenced tables

Query below lists tables that are most referenced by other tables with foreign keys. Those are the dictionary tables such as person, product or store. In data warehouses those are dimension tables.

select schema_name(tab.schema_id) + '.' + tab.name as [table],
   count(fk.name) as [references],
   count(distinct fk.parent_object_id) as referencing_tables
from sys.tables as tab
   left join sys.foreign_keys as fk
       on tab.object_id = fk.referenced_object_id
group by schema_name(tab.schema_id), tab.name
having count(fk.name) > 0
order by 2 desc

Sample results:

Columns:

  • table - name of the table with schema name
  • references - number of foreign keys referencing to this table
  • referencing_tables - number of different tables referencing to this table

7. Tables with most FKs

Query below lists tables with their number of foreign keys and number of tables they refer to.

select schema_name(fk_tab.schema_id) + '.' + fk_tab.name as [table],
    count(*) foreign_keys,
    count (distinct referenced_object_id) referenced_tables
from sys.foreign_keys fk
    inner join sys.tables fk_tab
        on fk_tab.object_id = fk.parent_object_id
group by schema_name(fk_tab.schema_id) + '.' + fk_tab.name
order by count(*) desc

Sample results:

Columns:

  • table - table with schema name
  • foreign_keys - number of foreign keys in a table
  • referenced_tables - number of referenced tables. Note that it is not the same as number of foreign keys, as multiple foreign keys may reference the same table.

Create documentation of your databases in minutes

You can get interactive HTML documetation of your database in a couple of minutes with Dataedo.

See live HTML data dictionary sample

Try it for free now