Insert-Select表示同一个表中多行的单个结果

时间:2013-11-23 10:40:41

标签: sql distinct insert-select

我不知道这个问题的标题是否有意义,但请允许我解释我的问题。

我有这样的表格。

DocTag表

DocId | TagId
   10 | 8
   10 | 45
   11 | 2
   11 | 15
   12 | 9
   12 | 32
   13 | 8
   13 | 15

标签表

TagId | TagName
    8 | HomePage
    2 | Private
   45 | IssuerNameOne
   15 | IssuerNameTwo
   32 | IssuerNameThree
    9 | TagThatNeedsToBeSkipped
 3000 | NewTag

DocTag表包含来自Document和Tag表的FK。现在我必须选择那些带有id 8或2以及其他id之一的文档(例如:45,32,15),当我发现此表中的Document时,我必须插入[DocId | 3000],其中3000是新标签的id。

换句话说,我必须选择属于HomePage或Private的文档以及提到的发行者之一,并为该文档分配新标记。

我有数百万个文档和数百个标签,以及72个不同的发行人,所以我想我必须为每个发行人执行72次查询。

对于“IssuerNameOne”,选择查询的结果应为:

DocId
   10       

因为8和45 TagIds。

对于“IssuerNameTwo”,选择查询的结果应为:

DocId
   11
   13

因为有2个,8个和15个TagIds。

插入执行后,DocTag应如下所示:

DocId | TagId
   10 | 8
   10 | 45
   11 | 2
   11 | 15
   12 | 9
   12 | 32
   13 | 8
   13 | 15
   10 | 3000
   11 | 3000
   13 | 3000

2 个答案:

答案 0 :(得分:1)

--INSERT INTO DocTag  (DocId,TagId)
SELECT DISTINCT DocId, 3000
FROM DocTag  t1 
WHERE TagId IN(8,2)
-- Check the DocId also has a TagId `IN(45,32,15)`
AND EXISTS (SELECT 1 FROM DocTag  t2 
            WHERE t2.DocId=t1.DocId AND t2.TagId IN(45,32,15))
-- Check the new tag mapping doesn't already exists
AND NOT EXISTS(SELECT 1 FROM DocTag  t3 
               WHERE t3.DocId=t1.DocId AND t3.TagId=3000)

Fiddle

答案 1 :(得分:1)

insert into DocTag  
select d.docId, 3000 from DocTag d
join DocTag d1 on d1.docId = d.docId and d1.tagId in (45, 32, 15)
 where d.tagId in (8, 2)
and not exists (select * from DocTag where docId = d.docId);