将父表中的每一行插入到子表中

发布于 2024-12-24 17:05:14 字数 942 浏览 1 评论 0原文

我的数据库看起来像这样,

tblAudits
PK AuditID
AuditStatus nvarchar(50)

tblQuestionDefs
PK QuestionID

tblAuditAnswers
PK AnswerID
FK AuditID
FK QuestionID

我最近在审核中添加了一些新问题,并且我想为所有活动审核中的每个新问题添加答案记录。在 SQL 中执行此操作的最佳方法是什么?我知道我可以使用游标循环,但据我所知,这些都非常慢。有什么基于集合的方法吗?

这是基于光标的代码

declare
    @AuditID int

declare AuditsCursor cursor fast_forward for
    select AuditID from tblAudits where AuditStatus='Issued' or AuditStatus='Pending' order by AuditID desc

open AuditsCursor
fetch next from AuditsCursor
into @AuditID

while @@FETCH_STATUS = 0
begin

    insert into tblAuditAnswers (AuditID, QuestionID)
    select @AuditID as AuditID, QuestionID
    from tblQuestionDefs
    where QuestionID not in (
        select QuestionID from tblAuditAnswers where AuditID=@AuditID
    )

fetch next from AuditsCursor
into @AuditID
end

close AuditsCursor
deallocate AuditsCursor

My DB looks like this

tblAudits
PK AuditID
AuditStatus nvarchar(50)

tblQuestionDefs
PK QuestionID

tblAuditAnswers
PK AnswerID
FK AuditID
FK QuestionID

I've recently added some new questions to the audits and I want to add an answer record for each new question to all active audits. What is the best way to do this in SQL? I know I can use cursors or loops, but those are both very slow AFAIK. Any set-based way to do it?

Here's the cursor based code

declare
    @AuditID int

declare AuditsCursor cursor fast_forward for
    select AuditID from tblAudits where AuditStatus='Issued' or AuditStatus='Pending' order by AuditID desc

open AuditsCursor
fetch next from AuditsCursor
into @AuditID

while @@FETCH_STATUS = 0
begin

    insert into tblAuditAnswers (AuditID, QuestionID)
    select @AuditID as AuditID, QuestionID
    from tblQuestionDefs
    where QuestionID not in (
        select QuestionID from tblAuditAnswers where AuditID=@AuditID
    )

fetch next from AuditsCursor
into @AuditID
end

close AuditsCursor
deallocate AuditsCursor

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

小镇女孩 2024-12-31 17:05:14
insert into tblAuditAnswers (AuditID, QuestionID)
select A.AuditID, QD.QuestionID
from tblAudits as A
  cross join tblQuestionDefs as QD
where (A.AuditStatus='Issued' or A.AuditStatus='Pending') and
        not exists (select *
                    from tblAuditAnswers as AA
                    where QD.QuestionID = AA.QuestionID and
                          A.AuditID = AA.AuditID)

https://data.stackexchange.com/stackoverflow/q/123061/

insert into tblAuditAnswers (AuditID, QuestionID)
select A.AuditID, QD.QuestionID
from tblAudits as A
  cross join tblQuestionDefs as QD
where (A.AuditStatus='Issued' or A.AuditStatus='Pending') and
        not exists (select *
                    from tblAuditAnswers as AA
                    where QD.QuestionID = AA.QuestionID and
                          A.AuditID = AA.AuditID)

https://data.stackexchange.com/stackoverflow/q/123061/

若相惜即相离 2024-12-31 17:05:14
INSERT INTO tblAuditAnswers
            (AuditID,
             QuestionID)
SELECT A.AuditID,
       Q.QuestionID
FROM   tblAudits A
       CROSS JOIN (SELECT QuestionID
                   FROM   tblQuestionDefs
                   EXCEPT
                   SELECT QuestionID
                   FROM   tblAuditAnswers) Q
WHERE  A.AuditStatus IN ( 'Issued', 'Pending' ) 
INSERT INTO tblAuditAnswers
            (AuditID,
             QuestionID)
SELECT A.AuditID,
       Q.QuestionID
FROM   tblAudits A
       CROSS JOIN (SELECT QuestionID
                   FROM   tblQuestionDefs
                   EXCEPT
                   SELECT QuestionID
                   FROM   tblAuditAnswers) Q
WHERE  A.AuditStatus IN ( 'Issued', 'Pending' ) 
浊酒尽余欢 2024-12-31 17:05:14

不需要游标。

INSERT INTO tblAuditAnswers
    (AuditID, QuestionID)
SELECT
    A.AuditID, Q.QuestionID
FROM
    tblAudits A
    CROSS JOIN tblQuestionDefs Q
    LEFT JOIN tblAuditAnswers AA
        ON A.AuditID = AA.AuditID AND Q.QuestionID = AA.QuestionID
WHERE
    A.AuditStatus='Issued' OR A.AuditStatus='Pending' AND
    AA.AuditID IS NULL
ORDER BY
    A.AuditID DESC

如果问题定义与特定审核类型相关,那么您还应该将 CROSS JOIN 替换为 INNER JOIN:

INNER JOIN tblQuestionDefs Q
    A.AuditTypeID = Q.AuditTypeID

There is no need for cursors.

INSERT INTO tblAuditAnswers
    (AuditID, QuestionID)
SELECT
    A.AuditID, Q.QuestionID
FROM
    tblAudits A
    CROSS JOIN tblQuestionDefs Q
    LEFT JOIN tblAuditAnswers AA
        ON A.AuditID = AA.AuditID AND Q.QuestionID = AA.QuestionID
WHERE
    A.AuditStatus='Issued' OR A.AuditStatus='Pending' AND
    AA.AuditID IS NULL
ORDER BY
    A.AuditID DESC

If the question definitions are related to specific audit types, then you should also replace the CROSS JOIN by an INNER JOIN:

INNER JOIN tblQuestionDefs Q
    A.AuditTypeID = Q.AuditTypeID
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文