У меня есть две таблицы. 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 JOIN
s. Существует ли путь вокруг этого, или я ищу что-то еще полностью?
Попробуйте:
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
в соединение
добавьте 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)
Вы можете использовать это предложение where:
WHERE WO_BreakerRail.Date = @Date OR WO_BreakerRail.Date IS NULL
Условие предиката должно быть в предложении 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
Вы хотите отфильтровать свой 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 поддерживает подзапросы.)