И синтаксис во внешнем объединении? - PullRequest
2 голосов
/ 08 сентября 2011

это небольшая часть гораздо большего запроса, который, как я обнаружил, является проблемой.

Я пытаюсь добавить фильтр к своему внешнему объединению в дополнение к первичному ключу.Проблема в том, что я получаю результаты, которые имеют 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 ]

1 голос
/ 08 сентября 2011

Вам не нужна производная таблица здесь.

Помещая предложение 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'
1 голос
/ 08 сентября 2011

Обычно у вас всегда будет OrderHeader для данного OrderDetail, но у вас может не быть его со статусом 0, 1.

Делая левое соединение, вы получаете все для этого конкретного Sku, а затем, если заголовок заказа не имеет статуса 0, 1, эти столбцы будут NULL.

Я думаю, вы хотите ВНУТРЕННЕЕ СОЕДИНЕНИЕ . Но тогда это, как правило, эквивалентно помещению всего в WHERE , поэтому я уверен, что вы полностью описываете, что вы хотите получить здесь.

После просмотра изменений попробуйте следующее:

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
1 голос
/ 08 сентября 2011

При выполнении левого соединения вы говорите, что хотите получить все детали заказа, где skunum = xxxx, независимо от того, есть ли совпадения в таблице заголовка заказа.мне кажется, что вы хотите внутреннего соединения.Но, возможно, я недостаточно понимаю или у меня недостаточно информации.Внутреннее соединение вернет только все детали заказа, если отгрузка имеет статус 1 или 0 и скунум совпадает.

0 голосов
/ 08 сентября 2011

Попробуйте это:

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
0 голосов
/ 08 сентября 2011
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            
0 голосов
/ 08 сентября 2011

Не уверен, что это то, что вы ищете:

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.

...