Подтвердить что ты не робот

ВЕРНУТЬСЯ ВНУТРЕННЕЙ РАБОТЫ с предложением WHERE

У меня две таблицы. indRailType содержит список имен в паре с идентификационным значением, которое я использую в других таблицах, чтобы указать тип рельса. WO_BreakerRail содержит столбец даты и столбец рельсового кода, соответствующий тому же коду в indRailType и некоторым другим данным. Для каждой операции на каждом типе рельса для каждой даты есть строка в WO_BreakerRail. Таким образом, у меня могло бы быть 3 строки, датированные 3/19/2010, каждая строка указывает другой код рельса и что произошло.

Когда я использую следующий LEFT OUTER JOIN, я получаю таблицу со всеми типами рельсов с нулями в строках, где ничего не произошло на 19-м. Теперь это работает, потому что у меня есть только одна дата, представленная в моей таблице WO_BreakerRail прямо сейчас, 19-го. Когда я добавлю несколько строк с разными датами, все будет схоже.

Это мой оператор SQL, который прямо сейчас дает мне именно те результаты, которые я хочу:

SELECT WO_BreakerRail.ID, indRailType.RailType, WO_BreakerRail.CreatedPieces, 
    WO_BreakerRail.OutsideSource, WO_BreakerRail.Charged, 
    WO_BreakerRail.Rejected, WO_BreakerRail.RejectedToCrop
FROM indRailType
LEFT OUTER JOIN WO_BreakerRail 
    ON indRailType.RailCode = WO_BreakerRail.RailCode

Теперь, когда я добавляю в предложение WHERE WO_BreakerRail.Date = @Date, я теряю все строки в JOIN, которые ничего не произошло. Я не хочу этого. От чтения это звучит как FULL OUTER JOIN - это то, что я хочу, но SQL Server Compact Edition не поддерживает FULL OUTER JOIN s. Есть ли способ обойти это, или я ищу что-то еще полностью?

4b9b3361

Ответ 1

Try:

SELECT WO_BreakerRail.ID, indRailType.RailType, WO_BreakerRail.CreatedPieces, 
    WO_BreakerRail.OutsideSource, WO_BreakerRail.Charged,
    WO_BreakerRail.Rejected, WO_BreakerRail.RejectedToCrop
FROM indRailType
LEFT OUTER JOIN WO_BreakerRail ON indRailType.RailCode = WO_BreakerRail.RailCode 
            AND WO_BreakerRail.Date = @Date

Таким образом, добавив AND WO_BreakerRail.Date = @Date к соединению

Ответ 2

Условие предиката должно быть в предложении On для соединения, а не в предложении where. Как работают внешние соединения, после анализа условий соединения все строки из "внешней стороны", которые не соответствуют внутренней стороне, добавляются обратно... Но все это происходит до того, как предложение where будет обработано. Поэтому, если предикат where where отключает атрибут с внешней стороны внешнего соединения, все эти строки будут удалены снова... (Все они равны нулю). Вместо этого поставьте предикат в условие соединения, затем он будет оценен до того, как недостающие строки будут добавлены обратно в...

SELECT b.ID, t.RailType, b.CreatedPieces, 
       b.OutsideSource, b.Charged, b.Rejected, 
       b.RejectedToCrop 
FROM indRailType t
   LEFT JOIN WO_BreakerRail b
        ON t.RailCode = b.RailCode 
            And b.Date = @Date

Ответ 3

Вы можете использовать это предложение where:

WHERE WO_BreakerRail.Date = @Date OR WO_BreakerRail.Date IS NULL

Ответ 4

добавьте WO_BreakerRail.Date = @Date в оператор LEFT OUTER JOIN, а не WHERE:

SELECT
    WO_BreakerRail.ID, indRailType.RailType, WO_BreakerRail.CreatedPieces, WO_BreakerRail.OutsideSource, WO_BreakerRail.Charged, WO_BreakerRail.Rejected, WO_BreakerRail.RejectedToCrop
    FROM indRailType 
        LEFT OUTER JOIN WO_BreakerRail ON indRailType.RailCode = WO_BreakerRail.RailCode AND WO_BreakerRail.Date = @Date

или вы можете добавить его в ГДЕ:

SELECT
    WO_BreakerRail.ID, indRailType.RailType, WO_BreakerRail.CreatedPieces, WO_BreakerRail.OutsideSource, WO_BreakerRail.Charged, WO_BreakerRail.Rejected, WO_BreakerRail.RejectedToCrop
    FROM indRailType 
        LEFT OUTER JOIN WO_BreakerRail ON indRailType.RailCode = WO_BreakerRail.RailCode
    WHERE (WO_BreakerRail.Date = @Date OR WO_BreakerRail.Date IS NULL)

Ответ 5

или вы можете добавить его в WHERE:

SELECT WO_BreakerRail.ID, indRailType.RailType, 
  WO_BreakerRail.CreatedPieces, 
  WO_BreakerRail.OutsideSource, WO_BreakerRail.Charged, 
  WO_BreakerRail.Rejected, WO_BreakerRail.RejectedToCrop 
FROM indRailType, WO_BreakerRailCode 
WHERE indRailType.RailCode = WO_BreakerRail.RailCode(+) 
 AND WO_BreakerRail.Date (+) [email protected] 

Ответ 6

Вы хотите отфильтровать ваш WO_BreakerRail до нужной даты, прежде чем LEFT JOINING его на indRailType. Если вы просто добавляете инструкцию WHERE, это делается наоборот, что приводит к описанной проблеме.

Предлагаемые решения должны работать (переместите условие в LEFT JOIN), но я хотел бы предложить альтернативу: вы можете использовать подзапрос, чтобы указать порядок, в котором должны быть выполнены:

SELECT R.ID, indRailType.RailType, R.CreatedPieces, R.OutsideSource, R.Charged, R.Rejected, R.RejectedToCrop
  FROM indRailType LEFT OUTER JOIN
       (SELECT * FROM WO_BreakerRail WHERE Date = @Date) R
       ON indRailType.RailCode = R.RailCode

(Untested, но, насколько я знаю, SQL Server CE поддерживает подзапросы.)