traer - Para ignorar las claves duplicadas durante ''copiar desde'' en postgresql
traer registros repetidos postgresql (4)
Tengo que volcar gran cantidad de datos del archivo a una tabla PostgreSQL. Sé que no es compatible con ''Ignorar'' ''reemplazar'', etc. como se hace en MySql. Casi todas las publicaciones relacionadas con esto en la web sugirieron lo mismo que arrojar los datos a una tabla temporal y luego hacer una ''inserción ... seleccionar ... donde no existe ...''.
Esto no ayudará en un caso, donde los datos del archivo en sí contenían claves primarias duplicadas. ¿Algún cuerpo tiene una idea sobre cómo manejar esto en PostgreSQL?
PD: estoy haciendo esto desde un programa Java, si ayuda
Inserte en una tabla temporal agrupada por la clave para que se deshaga de los duplicados
y luego insertar si no existe
La respuesta de Igor me ayudó mucho, pero también encontré el problema que Nate mencionó en su comentario. Entonces tuve el problema, tal vez además de la pregunta aquí, de que los nuevos datos no solo contenían duplicados internamente sino también duplicados con los datos existentes. Lo que funcionó para mí fue lo siguiente.
CREATE TEMP TABLE tmp_table AS SELECT * FROM newsletter_subscribers;
COPY tmp_table (name, email) FROM stdin DELIMITER '' '' CSV;
SELECT count(*) FROM tmp_table; -- Just to be sure
TRUNCATE newsletter_subscribers;
INSERT INTO newsletter_subscribers
SELECT DISTINCT ON (email) * FROM tmp_table
ORDER BY email, subscription_status;
SELECT count(*) FROM newsletter_subscribers; -- Paranoid again
Los duplicados interno y externo se vuelven iguales en tmp_table
y luego la parte DISTINCT ON (email)
elimina. El ORDER BY
se asegura de que la fila deseada aparezca primero en el conjunto de resultados y DISTINCT
descarta todas las filas adicionales.
PostgreSQL 9.5 ahora tiene funcionalidad upsert . Puedes seguir las instrucciones de Igor, excepto que INSERT final incluye la cláusula ON CONFLICT DO DO NADA.
INSERT INTO main_table
SELECT *
FROM tmp_table
ON CONFLICT DO NOTHING
Use el mismo enfoque que describió, pero DELETE
(o agrupe, o modifique ...) PK
duplicados en la tabla temporal antes de cargarlos en la tabla principal.
Algo como:
CREATE TEMP TABLE tmp_table
ON COMMIT DROP
AS
SELECT *
FROM main_table
WITH NO DATA;
COPY tmp_table FROM ''full/file/name/here'';
INSERT INTO main_table
SELECT DISTINCT ON (PK_field) *
FROM tmp_table
ORDER BY (some_fields)
Detalles: CREATE TABLE AS
, COPY
, DISTINCT ON