Click here to Skip to main content
Click here to Skip to main content

Visual Representation of SQL Joins

By , 3 Feb 2009
 

Introduction

This is just a simple article visually explaining SQL JOINs.

Background

I'm a pretty visual person. Things seem to make more sense as a picture. I looked all over the Internet for a good graphical representation of SQL JOINs, but I couldn't find any to my liking. Some had good diagrams but lacked completeness (they didn't have all the possible JOINs), and some were just plain terrible. So, I decided to create my own and write an article about it.

Using the code

I am going to discuss seven different ways you can return data from two relational tables. I will be excluding cross Joins and self referencing Joins. The seven Joins I will discuss are shown below:

  1. INNER JOIN
  2. LEFT JOIN
  3. RIGHT JOIN
  4. OUTER JOIN
  5. LEFT JOIN EXCLUDING INNER JOIN
  6. RIGHT JOIN EXCLUDING INNER JOIN
  7. OUTER JOIN EXCLUDING INNER JOIN

For the sake of this article, I'll refer to 5, 6, and 7 as LEFT EXCLUDING JOIN, RIGHT EXCLUDING JOIN, and OUTER EXCLUDING JOIN, respectively. Some may argue that 5, 6, and 7 are not really joining the two tables, but for simplicity, I will still refer to these as Joins because you use a SQL Join in each of these queries (but exclude some records with a WHERE clause).

Inner JOIN

INNER_JOIN.png

This is the simplest, most understood Join and is the most common. This query will return all of the records in the left table (table A) that have a matching record in the right table (table B). This Join is written as follows:

SELECT <select_list> 
FROM Table_A A
INNER JOIN Table_B B
ON A.Key = B.Key

Left JOIN

LEFT_JOIN.png

This query will return all of the records in the left table (table A) regardless if any of those records have a match in the right table (table B). It will also return any matching records from the right table. This Join is written as follows:

SELECT <select_list>
FROM Table_A A
LEFT JOIN Table_B B
ON A.Key = B.Key

Right JOIN

RIGHT_JOIN.png

This query will return all of the records in the right table (table B) regardless if any of those records have a match in the left table (table A). It will also return any matching records from the left table. This Join is written as follows:

SELECT <select_list>
FROM Table_A A
RIGHT JOIN Table_B B
ON A.Key = B.Key

Outer JOIN

FULL_OUTER_JOIN.png

This Join can also be referred to as a FULL OUTER JOIN or a FULL JOIN. This query will return all of the records from both tables, joining records from the left table (table A) that match records from the right table (table B). This Join is written as follows:

SELECT <select_list>
FROM Table_A A
FULL OUTER JOIN Table_B B
ON A.Key = B.Key

Left Excluding JOIN

LEFT_EXCLUDING_JOIN.png

This query will return all of the records in the left table (table A) that do not match any records in the right table (table B). This Join is written as follows:

SELECT <select_list> 
FROM Table_A A
LEFT JOIN Table_B B
ON A.Key = B.Key
WHERE B.Key IS NULL

Right Excluding JOIN

RIGHT_EXCLUDING_JOIN.png

This query will return all of the records in the right table (table B) that do not match any records in the left table (table A). This Join is written as follows:

SELECT <select_list>
FROM Table_A A
RIGHT JOIN Table_B B
ON A.Key = B.Key
WHERE A.Key IS NULL

Outer Excluding JOIN

OUTER_EXCLUDING_JOIN.png

This query will return all of the records in the left table (table A) and all of the records in the right table (table B) that do not match. I have yet to have a need for using this type of Join, but all of the others, I use quite frequently. This Join is written as follows:

SELECT <select_list>
FROM Table_A A
FULL OUTER JOIN Table_B B
ON A.Key = B.Key
WHERE A.Key IS NULL OR B.Key IS NULL

Examples

Suppose we have two tables, Table_A and Table_B. The data in these tables are shown below:

TABLE_A
  PK Value
---- ----------
   1 FOX
   2 COP
   3 TAXI
   6 WASHINGTON
   7 DELL
   5 ARIZONA
   4 LINCOLN
  10 LUCENT

TABLE_B
  PK Value
---- ----------
   1 TROT
   2 CAR
   3 CAB
   6 MONUMENT
   7 PC
   8 MICROSOFT
   9 APPLE
  11 SCOTCH

The results of the seven Joins are shown below:

-- INNER JOIN
SELECT A.PK AS A_PK, A.Value AS A_Value,
       B.Value AS B_Value, B.PK AS B_PK
FROM Table_A A
INNER JOIN Table_B B
ON A.PK = B.PK

A_PK A_Value    B_Value    B_PK
---- ---------- ---------- ----
   1 FOX        TROT          1
   2 COP        CAR           2
   3 TAXI       CAB           3
   6 WASHINGTON MONUMENT      6
   7 DELL       PC            7

(5 row(s) affected)
-- LEFT JOIN
SELECT A.PK AS A_PK, A.Value AS A_Value,
B.Value AS B_Value, B.PK AS B_PK
FROM Table_A A
LEFT JOIN Table_B B
ON A.PK = B.PK

A_PK A_Value    B_Value    B_PK
---- ---------- ---------- ----
   1 FOX        TROT          1
   2 COP        CAR           2
   3 TAXI       CAB           3
   4 LINCOLN    NULL       NULL
   5 ARIZONA    NULL       NULL
   6 WASHINGTON MONUMENT      6
   7 DELL       PC            7
  10 LUCENT     NULL       NULL

(8 row(s) affected)
-- RIGHT JOIN
SELECT A.PK AS A_PK, A.Value AS A_Value,
B.Value AS B_Value, B.PK AS B_PK
FROM Table_A A
RIGHT JOIN Table_B B
ON A.PK = B.PK

A_PK A_Value    B_Value    B_PK
---- ---------- ---------- ----
   1 FOX        TROT          1
   2 COP        CAR           2
   3 TAXI       CAB           3
   6 WASHINGTON MONUMENT      6
   7 DELL       PC            7
NULL NULL       MICROSOFT     8
NULL NULL       APPLE         9
NULL NULL       SCOTCH       11

(8 row(s) affected)
-- OUTER JOIN
SELECT A.PK AS A_PK, A.Value AS A_Value,
B.Value AS B_Value, B.PK AS B_PK
FROM Table_A A
FULL OUTER JOIN Table_B B
ON A.PK = B.PK

A_PK A_Value    B_Value    B_PK
---- ---------- ---------- ----
   1 FOX        TROT          1
   2 COP        CAR           2
   3 TAXI       CAB           3
   6 WASHINGTON MONUMENT      6
   7 DELL       PC            7
NULL NULL       MICROSOFT     8
NULL NULL       APPLE         9
NULL NULL       SCOTCH       11
   5 ARIZONA    NULL       NULL
   4 LINCOLN    NULL       NULL
  10 LUCENT     NULL       NULL

(11 row(s) affected)
-- LEFT EXCLUDING JOIN
SELECT A.PK AS A_PK, A.Value AS A_Value,
B.Value AS B_Value, B.PK AS B_PK
FROM Table_A A
LEFT JOIN Table_B B
ON A.PK = B.PK
WHERE B.PK IS NULL

A_PK A_Value    B_Value    B_PK
---- ---------- ---------- ----
   4 LINCOLN    NULL       NULL
   5 ARIZONA    NULL       NULL
  10 LUCENT     NULL       NULL
(3 row(s) affected)
-- RIGHT EXCLUDING JOIN
SELECT A.PK AS A_PK, A.Value AS A_Value,
B.Value AS B_Value, B.PK AS B_PK
FROM Table_A A
RIGHT JOIN Table_B B
ON A.PK = B.PK
WHERE A.PK IS NULL

A_PK A_Value    B_Value    B_PK
---- ---------- ---------- ----
NULL NULL       MICROSOFT     8
NULL NULL       APPLE         9
NULL NULL       SCOTCH       11

(3 row(s) affected)
-- OUTER EXCLUDING JOIN
SELECT A.PK AS A_PK, A.Value AS A_Value,
B.Value AS B_Value, B.PK AS B_PK
FROM Table_A A
FULL OUTER JOIN Table_B B
ON A.PK = B.PK
WHERE A.PK IS NULL
OR B.PK IS NULL

A_PK A_Value    B_Value    B_PK
---- ---------- ---------- ----
NULL NULL       MICROSOFT     8
NULL NULL       APPLE         9
NULL NULL       SCOTCH       11
   5 ARIZONA    NULL       NULL
   4 LINCOLN    NULL       NULL
  10 LUCENT     NULL       NULL

(6 row(s) affected)

Note on the OUTER JOIN that the inner joined records are returned first, followed by the right joined records, and then finally the left joined records (at least, that's how my Microsoft SQL Server did it; this, of course, is without using any ORDER BY statement).

You can visit the Wikipedia article for more info here (however, the entry is not graphical).

I've also created a cheat sheet that you can print out if needed. If you right click on the image below and select "Save Target As...", you will download the full size image.

History

  • Initial release -- 02/03/2009.
  • Version 1.0 -- 02/04/2009 -- Fixed cheat sheet and minor typos.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

C.L. Moffatt
United States United States
Member
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralMy vote of 5memberFarhan Ghumra21 Sep '12 - 0:14 
Excellent
GeneralMy vote of 5memberwrecklass9 Sep '12 - 13:21 
Perfect way for people to visualize how these joins are done.
GeneralMy vote of 5memberMANISH RASTOGI11 Jun '12 - 2:30 
Very good article.
GeneralMy vote of 5memberSeniorCrispy14 May '12 - 5:57 
Clear and concise, a good reference.
QuestionThanks a lotmemberilneyo3 Apr '12 - 11:54 
Really useful article. Thank you.
GeneralMy vote of 5membertgurinder28 Mar '12 - 2:02 
Very easy ti understand the concept
GeneralMy vote of 5memberDazManCat28 Feb '12 - 6:37 
Handy if you forget your joins like I just did!
GeneralMy vote of 5membermanoj kumar choubey3 Feb '12 - 22:09 
Nice
GeneralMSSQL 2008 EXCEPT and INTERSECT (Transact-SQL)memberAndy Missico30 Nov '11 - 6:24 
EXCEPT and INTERSECT (Transact-SQL)
http://msdn.microsoft.com/en-us/library/ms188055.aspx[^]
GeneralRe: MSSQL 2008 EXCEPT and INTERSECT (Transact-SQL)memberC.L. Moffatt30 Nov '11 - 9:07 
The EXCEPT and INTERSECT operators will not give you the same results as my examples above. Did you try using the EXCEPT and INTERSECT operators with the data I have given?
 
The EXCEPT and INTERSECT operators are limiting UNION operators. To use them the SELECT statements must be identical.
 
The EXCEPT operator would work showing me which keys were in the left table and not in the right table but I could not get any other column information from the left table.
 
The INTERSECT operator is kind of like an INNER JOIN operator with a DISTINCT operator.
 
Neither of these will accomplish what I have described in the article above.
 
Let's use the LEFT EXCLUDING JOIN I have described above.
 
MY EXAMPLE
SELECT A.PK AS A_PK, A.Value AS A_Value
FROM Table_A A
LEFT JOIN Table_B B
ON A.PK = B.PK
WHERE B.PK IS NULL

YOUR SUGGESTION

 
SELECT A.PK AS A_PK, A.Value AS A_Value
FROM Table_A A
EXCEPT
SELECT B.PK, B.Value
FROM Table_B B
 

My example will return the expected results (I've added dashes and extra zeros just so the columns will line up).
A_PK----A_Value
0004----LINCOLN
0005----ARIZONA
0010----LUCENT
 
Your example will return something that is not expected (at least it isn't what we want in this case).
A_PK----A_Value
0001----FOX
0002----COP
0003----TAXI
0004----LINCOLN
0005----ARIZONA
0006----WASHINGTON
0007----DELL
0010----LUCENT
 
Your suggestion will yield us a LEFT JOIN because we want to include the VALUE field.
 
Your suggestion of using the INTERSECT operator will actually yield no results. Run the query below.
 
SELECT A.PK AS A_PK, A.Value AS A_Value
FROM Table_A A
INTERSECT
SELECT B.PK, B.Value
FROM Table_B B
 
There will be no instances where both the primary keys and the values match (at least using my data examples).
 
The EXCEPT and INTERSECT operators are useful, but they are not the same as the examples shown above.
 
I hope this clarifies things.
GeneralRe: MSSQL 2008 EXCEPT and INTERSECT (Transact-SQL)memberAndy Missico30 Nov '11 - 10:44 
I did not post a question, it was just a post to add a reference to other alternatives for others.
GeneralThe best introduction to joinsmembergdhgasyue16 Nov '11 - 20:50 
5 from me Smile | :)
GeneralRe: The best introduction to joinsmemberC.L. Moffatt30 Nov '11 - 9:09 
Thank you.
GeneralMy vote of 5memberoperations12 Nov '11 - 3:02 
This article is helpful and clear enough. Finally, I understood how ANSI Sql joins work Smile | :)
 
Thanks a million!
GeneralRe: My vote of 5memberC.L. Moffatt30 Nov '11 - 9:09 
Thank you!
QuestionMy vote of 5memberDrazen Pupovac31 Oct '11 - 0:34 
Really useful article. Thank you.
GeneralMy vote of 5memberA-Lexo28 Sep '11 - 23:23 
Very informative graphs.
SuggestionFew more things to addmembershantanufrom438719 Jul '11 - 21:26 
I found pretty good link to add some more stuff to this article. Check this
GeneralRe: Few more things to addmemberC.L. Moffatt20 Jul '11 - 9:21 
I don't see how your article adds to the article above.
GeneralMy vote of 5memberReiss12 Jul '11 - 10:30 
Nice use of set theory Smile | :)
GeneralMy vote of 5memberead mahmoud19 Apr '11 - 2:58 
very clear. good work
GeneralMy vote of 5memberDaveAuld17 Apr '11 - 22:39 
First time i have seen the different joins represented in this way together on one page, and it makes it so much clearer......
GeneralMy vote of 5memberdcialdella16 Feb '11 - 4:59 
Simple ! Great !
GeneralMy vote of 5memberVijay Chandra Sekhar Parepalli12 Feb '11 - 15:58 
Best and simple I have seen so far for helping understand SQL using Venn diagrams. Good one.
GeneralMy vote of 5memberWayne Clarke1 Feb '11 - 5:08 
Excellent resource to have; especially for those queries you don't use often. I would like to see this mixed with LINQ-to-SQL as well.
GeneralMy vote of 5memberSteve Maier24 Jan '11 - 9:26 
Great little summary. I hate trying to remember how they go.
Generalmy vote of 5memberYusuf8 Jan '11 - 16:45 
Excellent article. +5

GeneralJOINSmemberthinkindia10 Dec '10 - 1:55 
REALLY  VERY VERY USEFULL

GeneralMy vote of 5memberlinuxjr23 Nov '10 - 1:53 
Nice Article. Thanks for sharing your work.
GeneralThis assumes no NULL for keysmemberLenzM3 Nov '10 - 18:34 
The last three examples assume that NULL is not a valid key.
GeneralRe: This assumes no NULL for keysmemberC.L. Moffatt28 Jan '11 - 5:46 
By default, NULL is an invalid key. You can override this setting within SQL but I cannot think of a good reason why you would do this. What is the purpose of having a primary key if you are going to set it to NULL? Also in MS-SQL, you can override this feature but only one record can have the NULL primary key (because the key needs to be unique).
 
So yes, the examples assume that NULL is not being used as a key which I think is a safe and logical assumption.
GeneralMy vote of 5membersomnath _chowdhury29 Oct '10 - 0:54 
Good Explanation
GeneralMy vote of 5memberChristophe30 Sep '10 - 2:53 
the beauty of simplicity
GeneralMy vote of 5membermaster vicky29 Sep '10 - 1:20 
Nice visual explanation Smile | :)
GeneralMy vote of 5memberPranay Rana22 Jul '10 - 1:44 
awesome........simply good , gr8
GeneralMy vote of 5memberza_10041719 Jul '10 - 0:55 
Nice!
GeneralMy vote of 5memberDarkRisingForce14 Jul '10 - 20:41 
Clear, Visual easy... Thank you
GeneralExcellent.memberdigital man11 Mar '10 - 23:23 
Can't believe I've not spotted this before: clear and easy to understand. Well done.
Tychotics
 
"The dinosaurs became extinct because they didn't have a space program. And if we become extinct because we don't have a space program, it'll serve us right!"
Larry Niven

GeneralGreat Article!!memberKhushi_G18 Feb '10 - 10:14 
great article!!
 

Thanks. Smile | :)
Generalgot my 5memberOmar Gamil18 Feb '10 - 3:37 
simple and amazing Wink | ;)
Generalgreat articlemembercrudeCodeYogi24 Jan '10 - 7:41 
great article about joins..exact point to point... Thanks!!
 
If you fail to plan, you plan to fail!
 
Books are as useful to a stupid person as a mirror is useful to a blind person. - Chanakya

GeneralExcillentgroupMd. Marufuzzaman30 Dec '09 - 1:59 
This is simply outstanding...
 
Thanks
Md. Marufuzzaman


Don't forget to click [Vote] / [Good Answer] on the post(s) that helped you.
 
I will not say I have failed 1000 times; I will say that I have discovered 1000 ways that can cause failure – Thomas Edison.

Questionhow to add new table (after join) to a datagridviewmemberanahita2213 Aug '09 - 21:15 
hi,i have problem after joining them ,for adding the new table in datagrid view
how should i do it?
thanx for your nice jobRose | [Rose]
AnswerRe: how to add new table (after join) to a datagridviewmemberC.L. Moffatt17 Aug '09 - 10:58 
First, you'll have to be a little more specific. I'm really not sure what it is you are trying to accomplish.
Second, a datagridview is a little beyond the scope of this article. But if you are able to explain clearer what it is you are trying to do, I'll try to help you.
GeneralLeft outer join and right outer joinmemberudomnoke17 Jul '09 - 15:20 
Where is left and right outer join case is in.
GeneralRe: Left outer join and right outer joinmemberC.L. Moffatt17 Aug '09 - 10:59 
I don't understand your question.
GeneralRe: Left outer join and right outer joinmemberUnruled Boy27 Jul '11 - 1:39 
in sql server, we have:
 
SELECT <select_list>
FROM Table_A A
LEFT OUTER JOIN Table_B B
ON A.Key = B.Key
 
and
 
SELECT <select_list>
FROM Table_A A
RIGHT OUTER JOIN Table_B B
ON A.Key = B.Key
Regards,
unruledboy_at_gmail_dot_com
http://www.xnlab.com

GeneralRe: Left outer join and right outer joinmemberC.L. Moffatt27 Jul '11 - 11:52 
In SQL Server, the "OUTER" declaration is optional. You can easily write "LEFT JOIN" or "RIGHT JOIN" and the SQL Server will perform the exact same join. Try it.
 
So "LEFT JOIN" equals "LEFT OUTER JOIN" and "RIGHT JOIN" equals "RIGHT OUTER JOIN". They are the same thing.
GeneralRe: Left outer join and right outer joinmemberUnruled Boy27 Jul '11 - 16:54 
you are right Laugh | :laugh:
 
but I just want to explain your question, because you said " I don't understand your question." basically he just want you to mention left/right outer join explicitly in the article.Rose | [Rose]
Regards,
unruledboy_at_gmail_dot_com
http://www.xnlab.com

GeneralReally Good!memberMANISH RASTOGI25 Jun '09 - 21:03 
Thanks C.L. Moffatt

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web02 | 2.6.130516.1 | Last Updated 4 Feb 2009
Article Copyright 2009 by C.L. Moffatt
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid