Вставить в дочернюю таблицу для каждой строки в родительской таблице - PullRequest
2 голосов
/ 02 января 2012

Моя БД выглядит так

tblAudits
PK AuditID
AuditStatus nvarchar(50)

tblQuestionDefs
PK QuestionID

tblAuditAnswers
PK AnswerID
FK AuditID
FK QuestionID

Я недавно добавил несколько новых вопросов к аудитам и хочу добавить запись ответов на каждый новый вопрос ко всем активным аудитам. Каков наилучший способ сделать это в SQL? Я знаю, что могу использовать курсоры или циклы , но оба они очень медленные AFAIK. Есть ли какой-нибудь сет-способ сделать это?

Вот код курсора

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

Ответы [ 3 ]

3 голосов
/ 02 января 2012
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)

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

2 голосов
/ 02 января 2012
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' ) 
0 голосов
/ 02 января 2012

Курсоры не нужны.

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...