CodeForGood
CodeForGood

Reputation: 749

How to exclude a record with INNER/LEFT JOIN

There's a table called order_flags that I am trying to join with orders table with orders.id being the foreign key in order_flags as order_fk. All I need is to exclude an order whose foreign key record has value 7 set for 'order_flags.flag' field. The SQL that I am trying below returns empty records. I expect this to return all the records except for the one having 7 as value for flag field in order_flags table. Tables in the question are:

enter image description here

enter image description here

enter image description here

enter image description here

enter image description here

SELECT orders.id, 
       orders.po_number, 
       orders.payment_method, 
       order_flags.flag, 
       order_details.vendor_fk, 
       Max(order_details.estimated_shipped_date) AS estimated_shipped_date, 
       Max(back_orders.back_order_date)          AS back_order_date 
FROM   orders 
       INNER JOIN order_details 
               ON order_details.order_fk = orders.id 
       LEFT JOIN order_flags 
              ON order_flags.order_fk = orders.id 
       LEFT JOIN sku 
              ON sku.item_sku = order_details.sku 
       LEFT JOIN back_orders 
              ON back_orders.sku_fk = sku.id 
WHERE  orders.order_status = 'PL' 
       AND ( ( order_details.item_status = 'PL' ) 
              OR ( order_details.item_status = 'SN' ) ) 
       AND orders.placed_date >= '1969-07-03' 
       AND orders.flag_overdue_po = '1' 
       AND order_details.estimated_shipped_date != '0000-00-00' 
       AND order_details.vendor_fk NOT IN ( '57', '0', '72', '161' ) 
       AND order_flags.flag != '7' 
GROUP  BY orders.id, 
          order_details.vendor_fk 

Upvotes: 1

Views: 305

Answers (1)

O. Jones
O. Jones

Reputation: 108641

If in a WHERE clause you mention a column from a LEFT JOINed table, you convert the join to INNER JOIN.

You have this.

   FROM   orders 
      ...
   LEFT JOIN order_flags 
          ON order_flags.order_fk = orders.id 
      ...   
   WHERE ...  order_flags.flag != '7' 

Try moving the filter to the ON clause like this.

   FROM   orders 
      ...
   LEFT JOIN order_flags 
          ON order_flags.order_fk = orders.id 
         AND order_flags.flag != '7'
      ...   
   WHERE ... 

Or try this...

 WHERE ... (order_flags.flag IS NULL OR order_flags.flag != '7')

Why does this happen? If no row from the left of the LEFT JOIN matches a row from the right, the resultset of the join has NULLs for the columns from the left. NULLs are weird. They're not equal to anything, and they're not unequal to anything. So your WHERE filter eliminated lots of rows.

Upvotes: 1

Related Questions