20th Jun 2023 16 minutes read What Is a LEFT OUTER JOIN in SQL? 4 Practical Examples Tihomir Babic sql left join JOIN Table of Contents What Is a LEFT OUTER JOIN? What’s the Difference Between LEFT OUTER JOIN And LEFT JOIN? LEFT [OUTER] JOIN Syntax 4 Examples of LEFT OUTER JOIN The Dataset for Examples 1-3 Example 1: Find All Employees and Their Departments What If We Used an INNER JOIN? Example 2: List All Departments and Their Employees What If We Used an INNER JOIN? Example 3: List All Departments and the Number of Employees in Each What If We Used INNER JOIN? Dataset for Example 4 Example 4: List All the Artists, Their Albums, and the Grammy Award Category What If We Used INNER JOIN? Beginners’ Corner: Some Tips on Writing JOINs Choosing the Correct Join Deciding Which Table Is the Left One Be Careful With Aggregate Functions Cascading LEFT JOINs Looking For More LEFT JOIN Practice? Today’s article will discuss the LEFT OUTER JOIN in SQL. We’ll go through several examples of LEFT OUTER JOIN usage and compare it with INNER JOIN. A JOIN is an SQL feature that allows you to combine data from two or more tables. The nature of relational databases makes JOIN one of the most commonly used features in SQL. Why? In practice, you’ll very seldom have all the required data in one table. Even the most primitive databases consist of at least two tables. There are many different types of JOINs. We’ll focus on LEFT OUTER JOIN here. To get a comprehensive recap of different types of JOINs, try our interactive SQL JOINs course. Aside from the basics, it explains joining multiple tables and using self- and non-equi joins. You’ll complete over 90 hands-on exercises – all based on real-world examples! Let’s introduce LEFT OUTER JOIN; then we’ll make it more interesting with practical examples. If you need a refresher on some concepts as we go along, remember our SQL JOIN Cheat Sheet. What Is a LEFT OUTER JOIN? The most common JOIN is INNER JOIN. It’s a join type that returns only the matching rows from both joined tables. There are other JOIN types that can return rows from a joined table even if the row has no matching row in the other table. These types of JOINs are called outer joins. A LEFT JOIN is a type of outer join that outputs all rows from the left table and the matching rows from the right table. What’s the Difference Between LEFT OUTER JOIN And LEFT JOIN? Short answer: There’s no difference! Long answer: The full name of this type of join really is LEFT OUTER JOIN. You’ve probably seen SQL code examples where the tables are joined only with LEFT JOIN. This is because SQL accepts both LEFT OUTER JOIN and LEFT JOIN. As LEFT JOIN is shorter, it is used more often. When you see it, it simply means LEFT OUTER JOIN. The ‘Outer’ is implied, as there’s no other left join than a left outer join. LEFT [OUTER] JOIN Syntax The syntax of LEFT JOIN follows the standard JOIN syntax: Reference the first table in FROM. Use the LEFT JOIN keyword to reference the second table. Use the ON keyword to specify the joining condition. In other words, the syntax is: SELECT … FROM table_1 LEFT JOIN table_2 ON table_1.column = table_2.column; So how does LEFT OUTER JOIN work? In the generic example above, the query will reference table_1 and left join it with table_2. It will first return all the rows from table_1, no matter the joining condition. Why? Because this is the nature of LEFT JOIN – it returns all the rows from the left (i.e. first) table. Then the query will look at the joining condition – in this case, where a value in column from table_2 matches a value from column from table_1. The LEFT JOIN will return only values from the right (i.e. second table, or table_2) table where the joining condition is matched. When no such values are in the right table, the returned values will be NULL. You can see a visual example of this in our article on how the LEFT JOIN works. When the tables are joined, it goes without saying that you can choose any column from both tables in SELECT. Now that you know the syntax, the only thing left is to put it into practice. 4 Examples of LEFT OUTER JOIN The Dataset for Examples 1-3 First, let’s introduce the dataset. The first table, departments, has the following data: iddepartment_name 1Accounting 2Sales 5Compliance You can get the query for creating the table here. The second table is employees, and you can create it using this query. The table has the following data: idfirst_namelast_nameemaildepartment_id 1DellaHinchshawdhinchshaw@company.com1 2RoanaAndraudrandraud@company.com2 3NettleDrewellndrewell@company.com3 4CoralieLandreclandre@company.com3 5FredericaKetchasidefketchaside@company.com1 6FeneliaGuisotfguisot@company.com1 7MarysaPortchmportch@company.comNULL 8HarlenDrakardhdrakard@company.com2 9TiffieHauchthauch@company.comNULL 10LuraGravellslgravells@company.com1 11FaeLagdenflagden@company.com4 12ChuchoBearcbear@company.com4 13TracieBellisontbellison@company.com2 14CharitaMissencmissen@company.com1 15BearShoulderbshoulder@company.com1 Two employees have a NULL value in the column department_id. These are new employee records that haven’t been updated with the department yet. Example 1: Find All Employees and Their Departments Let’s use the above tables to list all the employees and their departments. This is an article about LEFT OUTER JOIN, so there’s no surprise: we’ll use exactly that join to solve this problem. Here’s the query: SELECT e.id, e.first_name, e.last_name, d.department_name FROM employees e LEFT JOIN departments d ON e.department_id = d.id ORDER BY e.id; The result data we need is the employees' ID numbers, names, and departments. That’s why these columns are in SELECT. To get all these columns, we need to access data from both tables. Let’s see how this is done. First, the table employees is referenced in FROM. Why this table and not the other one? Remember: Which table is referenced first matters in LEFT JOIN. Why? Because that table is the left table, and LEFT JOIN will return all the rows from that table no matter what. We reference the table employees first because we need to list all the employees from that table. Then we reference the table departments. We join both tables on the condition that the column department_id from the table employees is the same as the column id from the table departments. These two columns are shared dimensions (the primary key and foreign key) between these two tables, so they’re ideal for use in the join condition. To have more readable output, we order the results by employee ID: idfirst_namelast_namedepartment_name 1DellaHinchshawAccounting 2RoanaAndraudSales 3NettleDrewellNULL 4CoralieLandreNULL 5FredericaKetchasideAccounting 6FeneliaGuisotAccounting 7MarysaPortchNULL 8HarlenDrakardSales 9TiffieHauchNULL 10LuraGravellsAccounting 11FaeLagdenNULL 12ChuchoBearNULL 13TracieBellisonSales 14CharitaMissenAccounting 15BearShoulderAccounting The output lists all the employees – all 15 of them. It also shows their departments, which are ‘Accounting’ and ‘Sales’. You’ll notice that some employees have NULL values in the department_name column. Two of them we mentioned earlier: new employees without an updated department ID in the table. These had NULL values in the initial employees table, and are marked in blue. There are, however, other employees – marked in green – with NULL values. This is the result of the LEFT JOIN. All these employees have a department ID of 4, but the table departments doesn’t contain this value. It seems that the table departments might be calling for an update, too. A really shabby database for such a respectable fictive company! Remember: The values from the left table not found in the right table will be shown as NULL. What If We Used an INNER JOIN? Let’s write the above query again, this time with an INNER JOIN (usually abbreviated to just JOIN) instead of a LEFT JOIN: SELECT e.id, e.first_name, e.last_name, d.department_name FROM departments d JOIN employees e ON e.department_id = d.id ORDER BY e.id; The syntax is exactly the same; we just used a different join type. Let’s see what the result will be: idfirst_namelast_namedepartment_name 1DellaHinchshawAccounting 2RoanaAndraudSales 5FredericaKetchasideAccounting 6FeneliaGuisotAccounting 8HarlenDrakardSales 10LuraGravellsAccounting 13TracieBellisonSales 14CharitaMissenAccounting 15BearShoulderAccounting Some employees are missing; there are only nine here. Closer inspection shows that the employees with IDs 3, 4, 7, 9, 11, and 12 are not included in the result. Why? If you go back, you’ll see that the missing employees are those with NULLs in department_name in the LEFT OUTER JOIN output. Remember, INNER JOIN will return only matching rows from both tables – in other words, only those employees who have a department ID found in both tables. So in this situation, where we wanted all employees and their departments, the LEFT JOIN is the right choice. Now we also see the employees without the department, and we can tell our database needs updating. Example 2: List All Departments and Their Employees To get the desired result, we have to switch the order of the tables in LEFT JOIN. Here’s the query: SELECT d.id, d.department_name, e.first_name, e.last_name FROM departments d LEFT JOIN employees e ON d.id = e.department_id ORDER BY d.id; We tweak the order of the columns in SELECT to present the output better. Most of the columns are the same as before. This time, we’re selecting the department ID from the table departments, not the employee ID. Now, the table departments is our left table. This is because we want to show all departments from that table, whether or not they appear in the table employees – our right table. The ON condition stays the same; we only reversed the order of the columns. It really doesn’t matter; it could have remained in the same order. This is just for aesthetic reasons, as it’s easier to read the condition when it follows the order of the tables in LEFT JOIN. Also, we sort the output by department ID. Here’s the result: iddepartment_namefirst_namelast_name 1AccountingDellaHinchshaw 1AccountingFredericaKetchaside 1AccountingFeneliaGuisot 1AccountingLuraGravells 1AccountingCharitaMissen 1AccountingBearShoulder 2SalesHarlenDrakard 2SalesTracieBellison 2SalesRoanaAndraud 5ComplianceNULLNULL This output shows only nine employees, compared to 15 in the previous example. All employees with NULL values in the last example’s output do not appear in this output. The reason is, again, LEFT JOIN. As we made departments our left table, it listed all the departments and their employees. All the other employees are not here. Why? Either they have department ID 4, which doesn’t appear in the table departments, or they are new employees (remember them?) with NULL as a department ID. The only NULLs in this output appear in the last row. There’s the department ‘Compliance’, which doesn’t have any employees allocated to it. In other words, there are no employees with the value 5 in the column department_id of the employees table. Remember: The order of the tables in LEFT JOIN matters! What If We Used an INNER JOIN? Let’s change the query and use an INNER JOIN: SELECT d.id, d.department_name, e.first_name, e.last_name FROM departments d INNER JOIN employees e ON d.id = e.department_id ORDER BY d.id; The output is basically the same as when we inner joined Example 1. The only difference is that there is a department ID instead of an employee ID. Other than that, it’s the same, so we won’t spend time analyzing it. iddepartment_namefirst_namelast_name 1AccountingDellaHinchshaw 1AccountingFredericaKetchaside 1AccountingFeneliaGuisot 1AccountingLuraGravells 1AccountingCharitaMissen 1AccountingBearShoulder 2SalesHarlenDrakard 2SalesTracieBellison 2SalesRoanaAndraud Example 3: List All Departments and the Number of Employees in Each LEFT JOIN, like all other joins, is often used with SQL’s aggregate functions. This will come in handy here. Have a look at this query: SELECT d.department_name, COUNT(e.id) AS number_of_employees FROM departments d LEFT JOIN employees e ON d.id = e.department_id GROUP BY d.department_name; Let’s start explaining from the FROM clause. Since we want to list all the existing departments, we first refer to the table departments in FROM. Why? Because there are some employees without a department, and we don’t want them in our result. As we saw, there is also a department without employees; we want this department in the output regardless. Then follows the table employees after LEFT JOIN. The tables are joined on the same condition as in the previous example. To get the correct output, we need to list the department name in SELECT. We also need to use the COUNT(e.id) aggregate function to count the number of employee IDs. Why can’t we use COUNT(*)? Because it counts all the rows, including NULL values. This would skew our results. The compliance department has zero employees, which would have been shown as NULL when joined. COUNT(*) would have counted this NULL as one, which would not be accurate. The COUNT(e.id) option ignores NULL values and will count only employees whose ID is not NULL. This is more of an aggregate function topic than a LEFT JOIN topic, so we won’t go into further details. However, it is extremely important to understand when to use the various COUNT() options. You can refer to our article detailing all the different incarnations and uses of the COUNT() function for more information. Back to our code. After counting and joining, the output is grouped by the department name. All that will result in the list of departments with the number of employees in each department: department_namenumber_of_employees Accounting6 Compliance0 Sales3 The result shows there are, in total, nine employees across the company departments: six in Accounting, zero in Compliance, and three in Sales. What If We Used INNER JOIN? Now, let’s do the same query but with INNER JOIN. SELECT d.department_name, COUNT(e.id) AS number_of_employees FROM departments d JOIN employees e ON d.id = e.department_id GROUP BY d.department_name; Will the result be different? Let’s see. department_namenumber_of_employees Accounting6 Sales3 The result, again, shows there are nine employees across various departments. What is obviously missing is that the company has a Compliance department that’s not shown in this result. If we had used INNER JOIN, we would have concluded that there are only two departments in the company. LEFT JOIN was, again, the right choice since there may be (at least temporarily) a department without employees. Dataset for Example 4 We’ll use three tables in this example. The first one is artists; it contains the following data about musical artists: idartist_name 1Isaac Hayes 2Paul Simon 3Stevie Wonder 4George Benson Create the table using the query here. The next table is albums: idalbum_titleyear_releasedartist_idgrammy_category_id 1Caribou1974NULL2 2Still Crazy After All These Years197521 3Fulfillingness' First Finale197431 4Stranger to Stranger20162NULL 5The Wall1979NULL2 6Songs in the Key of Life197631 7Black Moses19711NULL 8Innervisions197431 9Shaft197112 10Let's Dance1983NULL2 And here’s the query to create this table. The query for the third table is here. The table is named grammy_award. It’s a list of Grammy award categories. It has only two categories: the best album winner and the best album nominee. idgrammy_category 1Album of the Year Winner 2Album of the Year Nominee Example 4: List All the Artists, Their Albums, and the Grammy Award Category LEFT JOIN can also be used to join more than two tables, and we’ll see how in the query below: SELECT artist_name, album_title, grammy_category FROM artists ar LEFT JOIN albums al ON ar.id = al.artist_id LEFT JOIN grammy_award ga ON al.grammy_category_id = ga.id; First, we listed all the required columns to show the artist's name, the album title, the year of release, and the Grammy Award category. We see from the presented tables that there are albums without artist information. Our catalog is incomplete, so the safest way to list all the available artists is to LEFT JOIN tables and consider the table artists as the left table. It is left joined with the table albums on the artist ID. To fetch the data about Grammys, we must somehow join the third table. How is this done? Simple: write the LEFT JOIN command again and reference the table grammy_award after it. This will LEFT JOIN albums with grammy_award. The tables are joined on the Grammy category ID. Let’s see the output: artist_namealbum_titlegrammy_category Isaac HayesShaftAlbum of the Year Nominee Isaac HayesBlack MosesNULL Paul SimonStranger to StrangerNULL Paul SimonStill Crazy After All These YearsAlbum of the Year Winner Stevie WonderInnervisionsAlbum of the Year Winner Stevie WonderSongs in the Key of LifeAlbum of the Year Winner Stevie WonderFulfillingness' First FinaleAlbum of the Year Winner George BensonNULLNULL The result shows all the artists, their albums, and whether the album was a nominee or a winner for the Album of the Year Award. It also shows the albums that were neither Grammy nominees nor winners. What If We Used INNER JOIN? Here’s the same code as above, with JOIN instead of LEFT JOIN: SELECT artist_name, album_title, grammy_category FROM artists ar JOIN albums al ON ar.id = al.artist_id JOIN grammy_award ga ON al.grammy_category_id = ga.id; Let’s see what the code returns: artist_namealbum_titlegrammy_category Isaac HayesShaftAlbum of the Year Nominee Paul SimonStill Crazy After All These YearsAlbum of the Year Winner Stevie WonderInnervisionsAlbum of the Year Winner Stevie WonderSongs in the Key of LifeAlbum of the Year Winner Stevie WonderFulfillingness' First FinaleAlbum of the Year Winner This result is incomplete. It’s missing one artist: George Benson. It’s also missing the albums without any Grammy category. Since we weren’t trying to list only the albums with a Grammy category, the LEFT JOIN was the right choice. Here are some additional explanations on how to LEFT JOIN multiple tables. Beginners’ Corner: Some Tips on Writing JOINs Here’s an overview of the most common mistakes beginners make when using the LEFT OUTER JOIN in SQL. We already covered them in the examples, but it might not be that obvious to a less experienced eye. So let’s put them into words. Choosing the Correct Join We compared all the LEFT JOIN examples with the INNER JOIN versions. As you saw, the output changes significantly. That’s why you need to carefully choose which join you’ll use. The best tip is to think about those two join definitions. So, if you need only matching data from two tables, then you need INNER JOIN. In all other cases, LEFT JOIN will probably be the correct choice. Deciding Which Table Is the Left One Once you choose to use the LEFT JOIN, how do you know which table should be the left table? First of all, the left one is the table that comes immediately after FROM. The right one is the one that comes after LEFT JOIN. But how do you decide which is which? You need to correctly understand the problem you’re solving. Look for cues in the wording and logic. If you need all employees, then the table with the employees will be the left one. In other words, if you think one of your tables needs to be shown unchanged, that’s your left table. Be Careful With Aggregate Functions Even if you make a mistake and choose the wrong join, it’s very likely that you’ll catch it in the output if you don’t aggregate the data. If you’re familiar with your data, you’ll see some rows missing or no NULLs where you expected them to be. However, be extra careful when using aggregate functions. As the output will be aggregated, it will be much more difficult to see the error from the output – unless you know all your data aggregation results by heart, which is highly unlikely. You wouldn’t need SQL in that case, would you? This is especially true when using COUNT(). As you saw in one of our examples, COUNT(*) can give you different results from COUNT(column_name). It’s extremely important that you know what you want to achieve and how COUNT() works. Remember: COUNT(column_name) ignores NULL values, while COUNT(*) doesn’t! So when working with aggregate functions, test your query with INNER JOIN – if you have the opportunity – and see if it returns different results. If it doesn’t, then it doesn’t matter which join you use. If it does, go back to your problem definition and see which join logic better suits your business logic. Cascading LEFT JOINs This is observed when joining more than two tables. If you choose to LEFT JOIN the first two tables, you usually have to LEFT JOIN all the other tables. You saw that in our last example, as we used two LEFT JOINs. Even if we used a LEFT JOIN first and then an INNER JOIN, we wouldn’t get the list of all the artists and the other data. Including INNER JOIN in this chain of joins will give the same result as using INNER JOIN instead of each LEFT JOIN. This is not always the case. But it’s quite a safe bet to follow this rule of thumb: if you need one LEFT JOIN, you need all LEFT JOINs. Looking For More LEFT JOIN Practice? This article gave you a taste of what a LEFT JOIN is and how to manage its occasional trickiness. We also practiced writing code as you got familiar with the LEFT JOIN syntax. To master all the nuances of LEFT OUTER JOIN in SQL, we recommend more practice. Three examples are not enough! To really build on what you learned here, we recommend our SQL JOINs course. Apart from theoretical foundations, you’ll also get plenty of hands-on practice with real-world scenarios. Here are some additional ideas on how to practice SQL JOINs. SQL JOINs interview questions are also a valuable resource for practicing materials. Happy learning! Tags: sql left join JOIN