Listar claves principales para todas las tablas - Postgresql

14

¿Hay alguna consulta que haga eso?

Encontré algunas consultas que pueden hacer esto para una tabla, pero no pude modificarla, así que puedo ver:

tablename | column | type
korda
fuente
1
Si estuviera preguntando esto, me gustaría saber la posición ordinal de una columna en la PK (algunas PK tienen más de 1 columna y el orden puede ser importante).
ypercubeᵀᴹ

Respuestas:

13

Algo como esto:

select tc.table_schema, tc.table_name, kc.column_name
from information_schema.table_constraints tc
  join information_schema.key_column_usage kc 
    on kc.table_name = tc.table_name and kc.table_schema = tc.table_schema and kc.constraint_name = tc.constraint_name
where tc.constraint_type = 'PRIMARY KEY'
  and kc.ordinal_position is not null
order by tc.table_schema,
         tc.table_name,
         kc.position_in_unique_constraint;
un caballo sin nombre
fuente
Esta consulta muestra no solo claves primarias sino también índices únicos
Michał Niklas
@ MichałNiklas no lo hace.
dezso
1
@DarielPratama: la condición tc.constraint_type = 'PRIMARY KEY'solo mostrará las claves principales. Sin embargo, cada clave principal está respaldada por un índice único
a_horse_with_no_name el
2
@a_horse_with_no_name Creo que esto es incorrecto. position_in_unique_constraintindica la posición para la clave EXTRANJERA, siempre es nula para las claves primarias. La columna correcta es ordinal_position. Probado en PG 9.4.
greatvovan
1
@a_horse_with_no_name He aprobado una edición sugerida por un usuario anónimo. No estoy seguro de si la edición se realizará, otros lo han rechazado. En cualquier caso, compruebe la sugerencia y el comentario anterior de greatvovan. Creo que son correctos y ordinal_positiondeberían usarse. El position_in_unique_constraintno es nulo solo en el uso de FK.
ypercubeᵀᴹ
20

Esta es una respuesta más precisa:

select tc.table_schema, tc.table_name, kc.column_name 
from  
    information_schema.table_constraints tc,  
    information_schema.key_column_usage kc  
where 
    tc.constraint_type = 'PRIMARY KEY' 
    and kc.table_name = tc.table_name and kc.table_schema = tc.table_schema
    and kc.constraint_name = tc.constraint_name
order by 1, 2;

Te perdiste la and kc.constraint_name = tc.constraint_nameparte, por lo que enumera todas las restricciones.

mikipero
fuente
2
Mientras su consulta funciona, la diferencia más importante es la and kc.position_in_unique_constraint is not nullparte que falta . Y le recomendamos encarecidamente que use ANSI JOIN (aunque muchos lo consideran una cuestión de gustos).
dezso
1

Por favor considere esto también. Esto generará el script para alterar todas las tablas.

SELECT STRING_AGG(FORMAT('ALTER TABLE %s CLUSTER ON %s;', A.table_name, A.constraint_name), E'\n') AS SCRIPT
FROM
(
    SELECT      FORMAT('%s.%s', table_schema, table_name) AS table_name, constraint_name
    FROM        information_schema.table_constraints
    WHERE       UPPER(constraint_type) = 'PRIMARY KEY'
    ORDER BY    table_name 
) AS A;
Martín
fuente
La pregunta no pregunta cómo alterar las tablas.
ypercubeᵀᴹ
1
Secundo lo que @ ypercubeᵀᴹ dice. Elimine esta respuesta, pero no se desanime: realice el recorrido, visite el centro de ayuda y lea el blog "ayúdenos a ayudarlo". En cuanto a responder algo que no se preguntó, todos lo hemos hecho muchas veces :-). ps bienvenido al foro!
Vérace
1

Creo que obtener la clave primaria y la clave externa deberían hacer esto. kc.position_in_unique_constraint no es nulo, esta condición solo puede obtener claves foráneas.

select tc.table_schema, tc.table_name, kc.column_name,tc.constraint_type
from 
    information_schema.table_constraints tc
    JOIN information_schema.key_column_usage kc 
        on kc.table_name = tc.table_name and kc.table_schema = tc.table_schema 
                and kc.constraint_name = tc.constraint_name
where 
--kc.position_in_unique_constraint is not null
order by tc.table_schema,
         tc.table_name,
         kc.position_in_unique_constraint;
Yuanwen Lee
fuente
Estoy tratando de hacer algo como esto (los nombres de las tablas son ligeramente diferentes, probablemente estoy en una versión diferente de postgres). La consulta se ejecuta pero no obtengo ningún resultado. ¿Es posible que no tenga los permisos correctos?
szeitlin