Мой запрос теряет данные в результате неполного предложения where - PullRequest
1 голос
/ 24 ноября 2010

Я знаю, что проблема в моем предложении WHERE, но у меня нет хорошего решения, чтобы исправить проблему.

если запись в разделе 2 не помечена как удаленная и связана с записью раздела 3, которая помечена как удаленная, тогда я полностью потеряю запись.

Любая помощь будет оценена.

p.s тоже самое происходит от 3 до 4 структура таблицы не может быть изменена, к сожалению ... до моего времени.

Table       FK         PK         bit
------------------------------------------
Section1 |  JobID   | Sect1ID | isDeleted
Section2 |  Sect1ID | Sect2ID | isDeleted
Section3 |  Sect2ID | Sect3ID | isDeleted
Section4 |  Sect3ID | Sect4ID | isDeleted

Хранимая процедура:

    @JobId int
    AS
SET NOCOUNT ON

SELECT J.Section1,
    J.Section2,
    J.Section3,
    J.Section4,
    S1.Id AS Section1Id,
    S1.[Order] + 1 AS S1Order,
    S1.Text AS S1Text,
    S2.Id AS Section2Id,
    S2.Text AS S2Text,
    S2.[Order] AS S2Order,
    S3.Id AS Section3Id,
    S3.Text AS S3Text,
    S3.[Order] + 1 AS S3Order,
    S4.Id AS Section4Id,
    S4.Text AS S4Text,
    S4.[Order] AS S4Order
       FROM JT_Jobs J 
       JOIN JT_Section1 S1 ON J.JobId = S1.JobId
  LEFT JOIN JT_Section2 S2 ON S1.Id = S2.Section1Id
  LEFT JOIN JT_Section3 S3 ON S2.Id = S3.Section2Id
  LEFT JOIN JT_Section4 S4 ON S3.Id = S4.Section3Id
      WHERE J.JobId = @JobId 
        AND S1.IsDeleted = 0
        AND (s2.IsDeleted is null or s2.IsDeleted = 0) 
        AND (s3.IsDeleted is null or s3.IsDeleted = 0) 
        AND (s4.IsDeleted is null or s4.IsDeleted = 0)
   ORDER BY S1.[Order], S2.[Order], S3.[Order], S4.[Order]

Ответы [ 3 ]

3 голосов
/ 24 ноября 2010

Поместите условия объединения в предложение join, а не в предложение where

  From JT_Jobs J
     Join JT_Section1 S1 
         On S1.JobId = J.JobId
            And S1.IsDeleted = 0
     Left Join JT_Section2 S2
         On S2.Section1Id=S1.Id 
            And (s2.IsDeleted is null or s2.IsDeleted = 0)  
     Left Join JT_Section3 S3 
         On S3.Section2Id = S2.iD
            And (s3.IsDeleted is null or s3.IsDeleted = 0)  
     Left Join JT_Section4 S4
         ON S4.Section3Id = S3.Id
            And (s4.IsDeleted is null or s4.IsDeleted = 0)    
  Where J.JobId = @JobId  

.... для объяснения, предикаты (логические условия) в предложении where оцениваются только после того, как все объединения имеютбыли обработаны.

Объединения обрабатываются (логически) путем изучения обеих сторон объединения, добавления записей в набор результатов, где выполняются все условия объединения, и затем , если этовнешнее соединение, добавляя обратно записи с внешней стороны, которые не имеют совпадающую запись на другой стороне.Таким образом, условия соединения применяются только к внутренней стороне и к записям на внешней стороне, которые соответствуют записи на внутренней стороне.

Таким образом, помещение условия в предложении where приводит к его применению к последнему промежуточному набору результатов после обработки всех объединений.В этот момент все эти внешние записи были добавлены обратно, и для условия, которое влияет на внешнюю сторону внешнего соединения, он удалит все те записи, которые были добавлены обратно во время второй половины этого внешнего соединения, эффективно его перевернув.обратно во внутреннее соединение.

0 голосов
/ 24 ноября 2010

Когда вы ссылаетесь на поля в предложении where (кроме случаев, когда ID равен нулю) для таблиц справа от левого соединения, вы превращаете его во внутреннее соединение. Вы должны поместить эти условия в критерии объединения.

0 голосов
/ 24 ноября 2010

Добавьте sN.IsDeleted = 0 к предложениям LEFT JOIN, а не к предложению WHERE.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...