简体   繁体   中英

MySQL JOIN: Only return rows where all values from right table are NULL

I have two MySQL tables like this:

orders:
+----------+------+
| order_id | name |
+----------+------+
| 1        | Mary |
| 2        | John |
| 3        | Anne |
+----------+------+

order_details:
+----------+----------------+
| order_id | shipped        |
+----------+----------------+
| 1        | null           |
| 1        | null           |
| 1        | SHIPPED-123ABC |
| 2        | null           |
| 2        | null           |
| 3        | SHIPPED-XYZ    |
| 3        | SHIPPED-XYZ    |
| 3        | null           |
+----------+----------------+

Now I want to join the order_details-table to the orders-table but only show the entries that only have NULL shipped values in the order_details table. So in this example only order_id #2 would get returned.

So the result would be:

+----------+------+---------+
| order_id | name | shipped |
+----------+------+---------+
| 2        | John | null    |
+----------+------+---------+

Thank you!

You can use not exists :

select o.order_id, o.name, null as shipped 
from orders o
where not exists (select 1 
                  from order_details od 
                   where od.order_id = o.order_id and od.shipped is not null
                 );

Simple aggregation with JOIN would also work :

select o.order_id, o.name, null as shipped
from orders o inner join
     order_details od
     on od.order_id = o.order_id
group by o.order_id, o.name
having min(od.shipped) = max(od.shipped) and min(od.shipped) is null;

If you want orders that have at least one row in order_details , then use aggregation:

select o.*
from (select od.order_id
      from order_details 
      group by od.order_id
      having count(shipped) = 0
     ) od join
     orders o
     on od.order_id = o.order_id;

If you want all such orders, even those with no rows in order_details , then use not exists :

select o.*
from orders o
where not exists (select 1
                  from order_details od
                  where od.order_id = o.order_id and
                        od.shipping is not null
                 );

Check whether below query gives what you want.

SELECT
  o.order_id,
  o.name,
  od.shipped
FROM
  orders o
  INNER JOIN order_details od ON od.order_id = o.order_id
WHERE
  od.shipped IS NULL
  AND od.shipped NOT IN     
(
SELECT od.shipped
WHERE
    od.shipped IS NOT NULL
     )

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