简体   繁体   中英

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:

在此处输入图片说明

在此处输入图片说明

在此处输入图片说明

在此处输入图片说明

在此处输入图片说明

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 

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM