我可以将此INSERT和DELETE查询放入单个INSERT查询中吗?

时间:2015-03-12 14:22:37

标签: sql postgresql insert duplicate-removal

如何将其放入一个查询中,关键点在于,当按名称对艺术家进行分组时,我需要考虑artist中的所有行,但我不想在artist_nodup中保留行表,如果它已经在mbartist_discogsartist表中。 (我正在使用Postgres 9.3)

INSERT INTO artist_nodup
SELECT
min(a1.id) as id,
a1.name
FROM artist  a1
GROUP BY a1.name
HAVING COUNT(*)=1
;

DELETE
FROM artist_nodup T1
WHERE exists
( select 1
   from mbartist_discogsartist T2
  where t1.id = t2.discogs_id
)
;

2 个答案:

答案 0 :(得分:1)

如果它足以避免INSERT中的冗余行,则无需从artist_nodup删除以前存在的行:

INSERT INTO artist_nodup
SELECT a.id, a.name
FROM   artist a
LEFT   JOIN artist a2 ON a2.name = a.name AND a2.id <> a.id
LEFT   JOIN mbartist_discogsartist m ON m.discogs_id = a.id
WHERE  a2.name IS NULL
AND    m.discogs_id IS NULL;

第一个LEFT JOIN排除来自artist的行,其中存在同名的其他行 第二个LEFT JOIN排除了来自artist的行mbartist_discogsartist中存在匹配ID的行( 替换 后来的DELETE )。

LEFT JOIN / IS NULL是执行此操作的几种技巧之一:

如果您还想排除artist_nodup中预先存在的行:

...
LEFT JOIN artist_nodup an ON an.name = a.name
...
AND an.name IS NULL

你得到了演习......

答案 1 :(得分:0)

您可以创建Stored Procedure

CREATE PROCEDURE sp_InsertDelete
AS
BEGIN
    INSERT INTO artist_nodup
    SELECT
    min(a1.id) as id,
    a1.name
    FROM artist  a1
    GROUP BY a1.name
    HAVING COUNT(*)=1
    ;
    GO
    DELETE
    FROM artist_nodup T1
    WHERE exists
    ( select 1
       from mbartist_discogsartist T2
      where t1.id = t2.discogs_id
    )
    ;
END

要使用这两个查询,您可以调用新创建的存储过程:EXECUTE sp_InsertDelete


或者您可以在TRIGGER表格上创建artist_nodup。当某些内容被插入artist_nodup表时,它会自动使用删除查询。

注意:如果您只需要在提供的插入查询后使用删除查询,这对您不起作用,因为在插入任何内容之后将始终使用此删除查询。

CREATE TRIGGER AutoDelete ON artist_nodup 
AFTER INSERT 
AS
BEGIN
     DELETE
     FROM artist_nodup T1
     WHERE exists
     ( select 1
        from mbartist_discogsartist T2
       where t1.id = t2.discogs_id
     )
     ;   
END;