如何将其放入一个查询中,关键点在于,当按名称对艺术家进行分组时,我需要考虑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
)
;
答案 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;