问题
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