ОСТАВЛЕННОЕ ВНЕШНЕЕ ОБЪЕДИНЕНИЕ с оператором 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

Теперь, когда я добавляю в a WHERE WO_BreakerRail.Date = @Date пункт я теряю все строки в JOIN который ничего не произошло. Я не хочу это. От чтения, это походит на ПОЛНОЕ OUTER JOIN то, что я хочу, но SQL Server Компактный Выпуск не поддерживает FULL OUTER JOINs. Существует ли путь вокруг этого, или я ищу что-то еще полностью?

21
задан Michał Powaga 1 May 2012 в 21:31
поделиться

5 ответов

Попробуйте:

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 в соединение

40
ответ дан 16 October 2019 в 23:29
поделиться

добавьте 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)
2
ответ дан 16 October 2019 в 23:29
поделиться

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

WHERE WO_BreakerRail.Date = @Date OR WO_BreakerRail.Date IS NULL
5
ответ дан 16 October 2019 в 23:29
поделиться

Условие предиката должно быть в предложении On для соединения, а не в предложении 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
15
ответ дан 16 October 2019 в 23:29
поделиться

Вы хотите отфильтровать свой WO_BreakerRail по желаемому date до LEFT СОЕДИНЯЯ его с 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

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

1
ответ дан 16 October 2019 в 23:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: