И синтаксис во внешнем объединении?
Это небольшой фрагмент гораздо большего запроса, который, как я обнаружил, является проблемой.
Я пытаюсь добавить фильтр к моему внешнему соединению в дополнение к первичному ключу. Проблема в том, что я получаю результаты, которые имеют StatusCode, отличный от 0 или 1, как если бы он игнорировал фильтр.
SELECT *
FROM Products P
LEFT OUTER JOIN OrderDetails OD ON OD.SkuNum = P.SkuNum
LEFT OUTER JOIN OrderHeader OH ON (OD.ShipmentNum = OH.ShipmentNum
AND (OH.StatusCode = 0 OR OH.StatusCode = 1))
WHERE P.SkuNum = XXXX
Обратите внимание, что если я добавлю этот оператор (OH.StatusCode = 0 ИЛИ OH.StatusCode = 1) в предложение where, он отфильтрует весь набор результатов по этим критериям, что тоже не то, что мне нужно.
Для этого соединения на простом английском я пытаюсь сказать: "Дайте мне все продукты и другие вещи, не перечисленные здесь. Если есть какие-либо поставки для этого продукта, дайте мне все детали для них, где статус доставки 1 или 0"
Мой синтаксис неверен или я что-то упустил? Благодарю.
Изменить: Обновлен запрос, чтобы включить продукты, чтобы сделать его более понятным, что я ищу, и исправил ошибку транспонирования.
6 ответов
Обычно у вас всегда будет OrderHeader для данного OrderDetail, но у вас может не быть его со статусом 0, 1.
Делая левое соединение, вы получаете все для этого конкретного Sku, а затем, если заголовок заказа не имеет статуса 0, 1, эти столбцы будут NULL
,
Я думаю, ты хочешь ВНУТРЕННЕГО СОЕДИНЕНИЯ. Но тогда это, как правило, было бы равносильно помещению всего в ГДЕ, поэтому я уверен, что вы полностью описываете, что вы хотите получить здесь.
После просмотра изменений попробуйте это:
SELECT *
FROM Products P
LEFT JOIN (
SELECT OD.SkuNum, OD.ShipmentNum, etc.
FROM OrderDetails OD
INNER JOIN OrderHeader OH
ON OD.ShipmentNum = OH.ShipmentNum
AND (OH.StatusCode = 0 OR OH.StatusCode = 1)
) AS Orders ON Orders.SkuNum = P.SkuNum
WHERE P.SkuNum = XXXX
Вам не нужна производная таблица здесь.
Размещая ON OD.SkuNum = P.SkuNum
последний пункт LEFT JOIN
По продуктам логически бывает последним.
SELECT *
FROM Products P
LEFT OUTER JOIN OrderDetails OD
INNER JOIN OrderHeader OH
ON OD.ShipmentNum = OH.ShipmentNum
AND OH.StatusCode IN ( 0, 1 )
ON OD.SkuNum = P.SkuNum
WHERE P.SkuNum = 'XXXX'
Делая левое соединение, вы говорите, что хотите получить все детали заказа, где skunum = xxxx, независимо от того, есть ли совпадения в таблице заголовков заказа.
Основываясь на вашем запросе и простом английском описании, для меня это звучит так, будто вы хотите внутреннее соединение. Но, возможно, я недостаточно понимаю или у меня недостаточно информации. Внутреннее соединение вернет только все детали заказа, если отгрузка имеет статус 1 или 0 и скунум совпадает.
Попробуй это:
SELECT *
FROM Products P
LEFT OUTER JOIN
( OrderDetails OD
INNER JOIN OrderHeader OH ON (OD.ShipmentNum = OH.ShipmentNum
AND (OH.StatusCode = 0 OR OH.StatusCode = 1))
) ON OD.SkuNum = P.SkuNum
WHERE P.SkuNum = XXXX
SELECT *
FROM Products P
LEFT JOIN (
SELECT OD.*
FROM OrderHeader OH
INNER JOIN OrderDetails OD
ON OH.ShipmentNum = OD.ShipmentNum
WHERE OH.StatusCode IN (0,1)
) as orders
ON P.SkuNum = orders.SkuNum
WHERE P.SkuNum = XXXX
Не уверен, что это то, что вы ищете:
SELECT *
FROM OrderHeader OH
LEFT OUTER JOIN OrderDetails OD ON OD.ShipmentNum = OH.ShipmentNum AND OD.SkuNum = XXXX
WHERE OH.StatusCode IN (0, 1)
Ваше заявление на простом английском языке, кажется, указывает на то, что вы ищете конкретную посылку. Возможно, вы захотите добавить shipmentnum к предложению where.