SQL Оператор обновления сервера на основе оператора выбора с несколькими значениями - PullRequest
0 голосов
/ 06 февраля 2020

У меня есть оператор Select, который хорошо работает, производя 7636 строк:

SELECT c.ClientId
    FROM   dbo.tblTreatment e
      JOIN dbo.tblProgramAssessment pa
    ON pa.TreatmentID = e.TreatmentId
      JOIN #Client c
    ON c.ClientId = e.ClientId
      LEFT JOIN dbo.tblCessationOfTreatment ct
    ON ct.TreatmentId = e.TreatmentId
      LEFT JOIN dbo.tblClientGP m
    ON m.ClientId = c.ClientId
    WHERE  e.IsOpen = 1 
    AND    e.IsDeleted = 0 
    AND    ct.CessationDate is null
    AND    c.IsDeceased = 0 

Я пытаюсь обновить эти 7636 строк, но вместо этого он обновляет 7446 строк. В моем (ограниченном) понимании, это, скорее всего, как-то связано с клиентурой. Вот заявление об обновлении:

UPDATE 
    #Client
SET 
    ToMigrate = 1
    , OpenTreatmentEpisodes = 1
WHERE 
    clientid in
    (SELECT c.ClientId
    FROM   dbo.tblTreatment e
      JOIN dbo.tblProgramAssessment pa
    ON pa.TreatmentID = e.TreatmentId
      JOIN #Client c
    ON c.ClientId = e.ClientId
      LEFT JOIN dbo.tblCessationOfTreatment ct
    ON ct.TreatmentId = e.TreatmentId
      LEFT JOIN dbo.tblClientGP m
    ON m.ClientId = c.ClientId
    WHERE  e.IsOpen = 1 
    AND    e.IsDeleted = 0 
    AND    ct.CessationDate is null
    AND    c.IsDeceased = 0  
)

Если я изменю 'IN' на '=', я получу сообщение об ошибке: Подзапрос вернул более 1 значения. Это недопустимо, если подзапрос следует =,! =, <, <=,>,> = Или когда подзапрос используется в качестве выражения. Оператор был прекращен.

1) Я не очень понимаю, почему есть разница в 7446 против 7636 строк. 2) Как я могу обновить только 7636 строк из оператора select?

Заранее спасибо!

1 Ответ

0 голосов
/ 06 февраля 2020

Как прокомментировал Ник, вы, вероятно, дублировали clientid в таблице #Client. В результате некоторые элементы, возвращаемые вашим подзапросом IN, совпадают с несколькими строками во внешнем запросе, что приводит к обновлению нежелательных строк.

Я думаю, что вы можете обойти эту проблему, используя возможности SQL Сервер обновляемый CTE. Это работает, превращая ваш запрос SELECT в CTE, а затем UPDATE непосредственно в CTE (учтите, что для этого CTE должен вернуть столбцы, которые необходимо обновить).

WITH cte AS (
    SELECT c.ToMigrate, c.OpenTreatmentEpisodes
    FROM dbo.tblTreatment e
    INNER JOIN dbo.tblProgramAssessment pa ON pa.TreatmentID = e.TreatmentId
    INNER JOIN #Client c ON c.ClientId = e.ClientId
    LEFT JOIN dbo.tblCessationOfTreatment ct ON ct.TreatmentId = e.TreatmentId
    LEFT JOIN dbo.tblClientGP m ON m.ClientId = c.ClientId
    WHERE  
           e.IsOpen = 1 
           AND e.IsDeleted = 0 
           AND ct.CessationDate is null
           AND c.IsDeceased = 0 
)
UPDATE cte SET ToMigrate = 1, OpenTreatmentEpisodes = 1
...