2014-12-19 5 views
0

Я работаю над проектом базы данных с postgres. У меня есть большая таблица, которая содержит данные, импортированные из файла csv, которые мне нужно перенести на другие более мелкие таблицы, которые представляют собой созданную мной базу данных.Передача данных между таблицами нарушение ограничения первичного ключа

Большая таблица с импортированными данными называется data_minerva, таблица, в которую я хочу передать часть данных, называется related_articles. Вот часть кода DDL:

CREATE SEQUENCE article_id_seq; 
CREATE TABLE article (
    article_id integer UNIQUE NOT NULL DEFAULT nextval('article_id_seq'), 
    title varchar, 
    body varchar, 
    publish_time timestamp, 
    creation_time timestamp, 
    id integer, 
    PRIMARY KEY (article_id), 
    FOREIGN KEY (id) REFERENCES team (id) 
); 
ALTER SEQUENCE article_id_seq OWNED BY article.article_id; 

CREATE TABLE related_articles (
    article_id1 integer NOT NULL, 
    article_id2 integer NOT NULL, 
    kind varchar, 
    PRIMARY KEY (article_id1, article_id2, kind), 
    FOREIGN KEY (article_id1) REFERENCES article (article_id), 
    FOREIGN KEY (article_id2) REFERENCES article (article_id) 
); 

Как вы можете видеть в приведенном выше фрагменте кода статьи определяется его ID. Таблица data_minerva не содержит столбец идентификатора. Теперь, когда я хочу передать данные от data_minerva до related_articles, я вхожу в беду, что есть дубликаты в таблице data_minerva, и они нарушают ограничение первичного ключа таблицы related_articles. Однако я попытался создать правило, чтобы игнорировать эти дубликаты, но без каких-либо успехов. Я думаю, мне нужно сделать что-то еще с SELECT DISTINCT, но я не могу понять это. Запрос, который я использую для передачи данных:

CREATE RULE "ignore" AS ON INSERT TO related_articles 
    WHERE EXISTS (SELECT 1 FROM related_articles WHERE article_id1=NEW.article_id1 AND article_id2=NEW.article_id2 AND kind=NEW.kind) 
DO INSTEAD NOTHING; 


INSERT INTO related_articles (article_id1, article_id2, kind) 
SELECT DISTINCT ON (data_minerva.articletitle, data_minerva.articlestarttime, data_minerva.writeremail,article.id, article.id, data_minerva.linkedarticletitle, data_minerva.linkedarticlestarttime) 
(SELECT article_id FROM article WHERE data_minerva.linkedarticletitle IS NOT NULL AND article.title=data_minerva.articletitle AND article.creation_time=data_minerva.articlestarttime::timestamp), 
(SELECT article_id FROM article WHERE article.title=data_minerva.linkedarticletitle AND article.creation_time=data_minerva.linkedarticlestarttime::timestamp), 
linkedtype FROM data_minerva, article WHERE data_minerva.linkedarticletitle IS NOT NULL; 
+0

Поиск "вставить, если не существует" –

ответ

1

Вам, вероятно, лучше служить, продумав эти строки.

select a1.article_id, a2.article_id, d.linkedtype 
from article a1 
inner join data_minerva d on a1.title = d.articletitle and a1.creation_time = d.articlestarttime 
inner join article a2 on a2.title = d.linkedarticletitle and a2.creation_time = d.linkedarticlestarttime 

Это возможно это должно быть select distinct вместо того, чтобы просто select. Вам также может потребоваться проверить нулевые заголовки статей, или вам может потребоваться обработать нулевые заголовки статей отдельно.

Как только вы удовлетворены тем, что этот запрос возвращает правильные строки, просто положите insert into related_articles сверху и запустите его.

Смежные вопросы