2013-11-23 44 views
0

我不知道这个问题的标题是否有意义,但请允许我解释我的问题。插入选择单个结果在同一个表中的多行

我有这样的桌子。

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表包含文档和标签表FK的。现在,我必须选择那些标签带有8或2和其他ID(例如:45,32,15)标签的文档,并且当我在该表中找到该文档时,我必须插入[DocId | 3000],其中3000是新标签的标识。

换句话说,我必须选择属于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 

回答

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

+0

谢谢您的帮助。它看起来像一个工作解决方案,不幸的是我不能在星期一之前测试它,所以我会在稍后发布。 再次感谢。 – bajicdusko

+0

虽然我放弃了插入新标签的解决方案,但这是正确的答案。 @Mark答案几乎相同。由于语法更清晰,这一个被加入。 谢谢。 – bajicdusko

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); 
+0

谢谢马克。基本上它与@TI提交的解决方案是一样的,所以我想它是100%的工作解决方案。我不能在星期一之前测试它,所以我会让你知道发生了什么事情:)。 – bajicdusko

相关问题