I have two tables: customer
and mailing
:
+==========+ +=============+
| customer | | mailing |
+==========+ +=============+
| id | | id |
+----------+ +-------------+
| name | | customer_id |
+----------+ +-------------+
| mailing_id |
+-------------+
Every time I send a mailing to a customer, I add a row in the mailings table with that mailing id. One mailing can be sent to multiple customers.
I want to have a sql call that returns all customers that have not yet received a certain mailing. How to ?
I am using mysql
select * from customer where id not in (
select customer_id from mailing where mailing_id = @mailing_id
)
SELECT * FROM customers c
JOIN mailings m
ON c.id = m.id
WHERE NOT EXISTS (
SELECT id
FROM mailings i
WHERE i.id = c.id
GROUP BY i.id
)
Something like
Select c.ID, c.Name
From Customers C
left Join mailing m On c.id = m.customer_id
where m.customer_id is null
What you describe is called an ANTI JOIN
. Usually there are three different ways for formulating it in SQL: A NOT IN
condition with a subquery, a NOT EXISTS
condition with a correlated subquery, or a LEFT JOIN
with a NOT NULL
condition. So for your query the possibilities are:
SELECT *
FROM customer
WHERE id NOT IN
( SELECT customer_id
FROM mailing)
SELECT *
FROM customer c
WHERE NOT EXISTS
( SELECT customer_id
FROM mailing m
WHERE m.customer_id = c.id)
SELECT *
FROM customer c
LEFT JOIN mailing m ON c.id = m.customer_id
WHERE m.customer_id IS NULL
This blog post compares the different possibilities with MySQL 5.1. According to it, LEFT JOIN / IS NULL
and NOT IN
are faster than NOT EXISTS
.
However, you should try for yourself which one is the fastest. That always depends on your data, indexes, ...
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.