You are on page 1of 5

Doing INTERSECT and MINUS in MySQL

By Carsten | October 3, 2005

Recently, I was asked to contribute a series of entries for the MySQL Network Knowledge
Base (to which you get access only if youre a MySQL Network subscriber).

I thought the following ones were kind of fun, so I asked the maintainer if I would be
allowed to post them here and maybe someone could tell me if Im completely off-track
or have suggestions for improvements.

Updated: My esteemed colleague Dean Ellis made me aware of a couple of issues with my
suggestions, so heres an update

Doing an INTERSECT

An INTERSECT is simply an inner join where we compare the tuples of one table with
those of the other, and select those that appear in both while weeding out duplicates. So

SELECT member_id, name FROM a


INTERSECT
SELECT member_id, name FROM b

can simply be rewritten to

SELECT a.member_id, a.name


FROM a INNER JOIN b
USING (member_id, name)

For more MySQL-related information om this site, see:


MySQL Pop Quizzes || MySQL Function of the Day
MySQL DATE_FORMAT() and PHP DATE() tool
Other MySQL blog entries

Performing a MINUS

To transform the statement

SELECT member_id, name FROM a


MINUS
SELECT member_id, name FROM b

into something that MySQL can process, we can utilize subqueries (available from MySQL
4.1 onward). The easy-to-understand transformation is:

SELECT DISTINCT member_id, name


FROM a
WHERE (member_id, name) NOT IN
(SELECT member_id, name FROM table2);

Of course, to any long-time MySQL user, this is immediately obvious as the classical use-
left-join-to-find-what-isnt-in-the-other-table:

SELECT DISTINCT a.member_id, a.name


FROM a LEFT JOIN b USING (member_id, name)
WHERE b.member_id IS NULL

which tends to be a lot more efficient.

Topics: MySQL |

31 Responses to Doing INTERSECT and MINUS in MySQL

1. Robin Says:
October 16th, 2005 at 9:31 pm

These examples are very usefull, however, I think it is important to comment that
internally something totally different happens. When you would do and
INTERSECT query for example, it would query the results from table A and table B
and then compare both sets. With the MySQL solution you describe it would query
all results from the first table and then do a lookup for each result in the second
table. This results in worse performance when your query returns a huge number of
results. For most uses your approach will be a good solution doh

2. Bidesh Mukherjee Says:


October 4th, 2006 at 1:44 pm

This is realy very helpful. i have across the fact that mysql 4.0 version
has lots of limitation. coming from oracle background it is difficult to think of
writting queries when you are not sure whether this will work or not. so this kind of
website proves to be very handy. Thank you

3. talunan Says:
May 4th, 2007 at 10:05 am

what if i have 3 tables or more to intersect with each other? thanks!

4. Tim-Hinnerk Heuer Says:


August 10th, 2007 at 8:21 am

I would assume for 3 or more tables you would do:


SELECT a.member_id, a.name
FROM a INNER JOIN b
USING (member_id, name) INNER JOIN c USING (member_id, name)
for intersect. Please correct me if Im wrong. Havent tried this.

5. Shubh Says:
November 21st, 2007 at 3:38 pm

I need to perform minus between two tables. But the only field I am using in select
statement is count(*). How to preform it?
Thanks in advance.

6. Wirtschaftsinformatik Blog Blog Archiv MySQL und MINUS Says:


December 1st, 2007 at 3:47 pm

[...] Alternativ kann man das auch mit einem Left Join lsen. Alle Varianten haben
mit dem Original-MINUS gemein, dass sie recht unperformant sind. (Gefunden
bei bitbybit) [...]

7. Bagesh Singh Says:


December 12th, 2007 at 7:54 am

hi INTERSECT is not working in mysql

my query is this

select user_id from answer_master where answer=abc and q_id=199


INTERSECT select user_id from answer_master where answer=abc and
q_id=198

8. Victor Anchidin Says:


December 15th, 2007 at 5:42 pm

Bahesh Singh, this article is about how to do an intersection in MySQL. Even if the
author refers abou INTERSECT, this statement doesnt exist in MySQL sql
language.

9. Gints Plivna Says:


January 3rd, 2008 at 6:21 pm

Actually statements
SELECT member_id, name FROM a
INTERSECT
SELECT member_id, name FROM b

and

SELECT a.member_id, a.name


FROM a INNER JOIN b
USING (member_id, name)
are functionally DIFFERENT.

INTERSECT and MINUS (EXCEPT) are operating on unique tuples, see example
(in Oracle but this is not relevant):

SQL> create table a (member_id number, name varchar(10));


Table created.
SQL> create table b (member_id number, name varchar(10));
Table created.
SQL> insert into a values (1, a);
1 row created.
SQL> insert into a values (1, b);
1 row created.
SQL> insert into a values (1, b);
1 row created.
SQL> insert into b values (1, b);
1 row created.
SQL> commit;
Commit complete.
SQL> SELECT member_id, name FROM a
2 INTERSECT
3 SELECT member_id, name FROM b
SQL> /
MEMBER_ID NAME
- -
1b
SQL> SELECT a.member_id, a.name
2 FROM a INNER JOIN b
3 USING (member_id, name)
SQL> /
SELECT a.member_id, a.name
*
ERROR at line 1:
ORA-25154: column part of USING clause cannot have qualifier
SQL> ed
Wrote file afiedt.buf
1 SELECT member_id, name
2 FROM a INNER JOIN b
3* USING (member_id, name)
SQL> /
MEMBER_ID NAME
- -
1b
1b
So as you can see retu

You might also like