2015-07-09 3 views
0

У меня есть база данных Postgresql с тремя таблицами, составляющими отношение «многие ко многим», article, author и article_authors. У меня есть запрос на основе this вопрос, который вставляет в article и author, если запись не существует, и возвращает id, и если он существует, то он возвращает id все равно:Вставить в таблицу соединений после возвращения нескольких идентификаторов

WITH article_s AS (
    SELECT id 
    FROM article 
    WHERE id = 25 
), 
article_i AS (
    INSERT INTO article 
    (id, web_id, article_title, pub_date, publishers_id) 
    SELECT 25, 'world/2013', 'a_title', '2015-07-07T21:58:28Z', 1 
    WHERE NOT EXISTS (SELECT 1 FROM article_s) 
    RETURNING id 
), 
author_s AS (
    SELECT id 
    FROM author 
    WHERE id = 34), 
author_i AS(
    INSERT INTO author (id, name) 
    SELECT 34, 'an_author' 
    WHERE NOT EXISTS (select 1 from author_s) 
    RETURNING id 
) 
SELECT article_i.id, author_i.id 
FROM article_i, author_i 
UNION ALL 
SELECT article_s.id, author_s.id 
FROM article_s, author_s; 

мне теперь нужно вставить возвращенный ID в article_authors, но не совсем уверен, как получить доступ к возвращенному ID, чтобы сделать это. Возможно ли это, или есть более элегантный способ решения этой проблемы? Заранее спасибо!

ответ

1

[непроверенных] Я думаю, что вы можете использовать COALESCE() плюс carthesian продукт, так как _I и _S CTS являются взаимоисключающими:

WITH article_s AS (
    SELECT id 
    FROM article 
    WHERE id = 3 
), 
article_i AS(
    INSERT INTO article (id, web_id, article_title, pub_date, publishers_id) 
    SELECT 3, 'world/2013', 'Queen hangs andrew', '2015-07-07T21:58:28Z', 1 
    WHERE NOT EXISTS (SELECT 1 FROM article_s) 
    RETURNING id 
), 
author_s AS (
    SELECT id 
    FROM author 
    WHERE id = 1 
), 
author_i AS (
    INSERT INTO author (id, name) 
    SELECT 1, 'Bill Bryson' 
    WHERE NOT EXISTS (select 1 from author_s) 
    RETURNING id 
) 
INSERT INTO article_authors (article_id, author_id) 
SELECT COALESCE(article_i.id, article_s.id) 
, COALESCE(author_i.id , author_s.id) 
FROM article_i, author_i 
    , article_s, author_s -- this is ugly 
    ; 
+0

спасибо за ответ, только просто на самом деле справляется с sql, поэтому я буду помнить об этом. – sammy88888888

0

Для потомков, это то, как я ее решил:

WITH article_s AS (
    SELECT id 
    FROM article 
    WHERE id = 3 
), 
article_i AS(
    INSERT INTO article (id, web_id, article_title, pub_date, publishers_id) 
    SELECT 3, 'world/2013', 'Queen hangs andrew', '2015-07-07T21:58:28Z', 1 
    WHERE NOT EXISTS (SELECT 1 FROM article_s) 
    RETURNING id 
), 
author_s AS (
    SELECT id 
    FROM author 
    WHERE id = 1 
), 
author_i AS (
    INSERT INTO author (id, name) 
    SELECT 1, 'Bill Bryson' 
    WHERE NOT EXISTS (select 1 from author_s) 
    RETURNING id 
) 
INSERT INTO article_authors (article_id, author_id) 
SELECT article_i.id, author_i.id 
FROM article_i, author_i 
UNION ALL 
SELECT article_s.id, author_s.id 
FROM article_s, author_s; 
+0

«UNION» обрабатывает только те случаи, когда ** оба автора и статья были вставлены или где ** ни один из них не был вставлен. Два случая, когда был вставлен только один из них, не покрываются (я надеюсь, что поля в таблице соединений не являются NULLable). См. Ответ 'COALESCE()'. – joop

+0

отлично, спасибо за это, это тот, с которым я пошел в конце! – sammy88888888

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