AND syntax in outer join?

笑着哭i 提交于 2019-12-24 00:40:07

问题


this is a small piece of a much larger query that I have discovered is a problem.

I'm trying to add a filter to my outer join in addition to the primary key. The problem is that I'm receiving results that have an StatusCode other than 0 or 1, as if it is ignoring the filter.

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

Note that if I put that statement (OH.StatusCode = 0 OR OH.StatusCode = 1) in the where clause it filters the entire result set by that criteria which is not what I want either.

For this join in plain english, I'm trying to say "Give me all products and other stuff not listed here. If there are any shipments for this product, give me all the details for them where the shipment has a status of 1 or 0"

Is my syntax wrong or am I missing something? Thanks.

Edit: Updated the query to include products to make it clearer what I'm looking for and fixed a transposition error.


回答1:


Typically you will always have an OrderHeader for a given OrderDetail, but you might not have one with status 0, 1.

By doing a left join, you are getting all for that particular Sku, and then if the order header doesn't have status 0, 1, those columns will be NULL.

I would think you want an INNER JOIN. But then that would usually be equivalent to putting everything in the WHERE, so I'm note sure you're fully describing what you want to get here.

After seeing your edit, try this:

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



回答2:


By doing a left join, you are saying you want all order details where skunum = xxxx regardless on if there is any matches in the order header table.

Based on your query and plain english description, to me it sounds like you want an inner join. But maybe I don't understand enough or have enough information. The inner join would only return all of the order details where the shipment has a status of 1 or 0 and the skunum matches.




回答3:


You don't need a derived table here.

By placing the ON OD.SkuNum = P.SkuNum clause last the LEFT JOIN on Products logically happens last.

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'



回答4:


Not sure if this is what you're looking for:

SELECT *
FROM OrderHeader OH
LEFT OUTER JOIN OrderDetails OD ON OD.ShipmentNum = OH.ShipmentNum AND OD.SkuNum = XXXX
WHERE OH.StatusCode IN (0, 1)

Your statement in plain english seems to idicate that you're looking for a specific shipment. You might want to add a shipmentnum to the where clause.




回答5:


Try this:

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



回答6:


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            


来源:https://stackoverflow.com/questions/7349475/and-syntax-in-outer-join

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!