What is the purpose (or use case) for an outer join in SQL? - sql

Is an outer join only used for analysis by the developer? I'm having trouble finding a use case for why you would want to include data in two or more tables that is unrelated or does not "match" your select criteria.

An example use case would be to produce a report that shows ALL customers and their purchases. That is, show even customers who have not purchased anything. If you do an ordinary join of customers and purchases, the report would show only those customers with at least one purchase.

Here is a very good list of examples by none other than Jeff Atwood - A Visual Explanation of SQL Joins he shows a new representation visually of the SQL joins.

The "doesn't match" case is useful for optional data. Something which is present for some rows, but not for others.

The OUTER JOIN is intended to address the cases where you wish to select a set of records from a primary table, which may or may not have related records contained in a secondary table.
An INNER join would omit from the list any primary records not also represented in the secondary table. Any OUTER JOIN guarantees the visiblity of all qualified primary records.

The difference between outer and inner joins is primarily that the outer joins retain each record from both the joined tables, whether the join predicate is matched or not. So a use case would need to revolve around knowing about "missing stuff", eg. customers who haven't made purchases, or members who have missing personal details.

Perhaps you have a users table and an address table related to it, since your users may choose not to enter an address, or they may have several (shipping, street, postal, etc). If you wanted to list all your users, but also display addresses for those that have them, you'd have to use an outer join for the address table.

Say you had two tables one for users and one for something like qualifications, you want to do a query that gets all users with their qualifications if they have any. In this case you would use an outer join to get all the users back and those with qualifications. An inner join would only give you the users who had a qualification.

A great article about outer joins:
Meet the experts: Terry Purcell on coding predicates in outer joins: A comparison of simple outer join constructs

Related

Select name for authors that havent written a book

We have to select authors that havent written a book but there are 3 different tables which makes me confused about how to write the join expression.
We have tables:
authors: author_id
authorships: author_id, book_id
books: book_id.
Obviously I selected the names from authors and tried inner join but it wont work for me. Help would be appreciated!
Since this sounds like a school assignment I won't give the full answer.
Try using an outer join between authors and authorship. Make sure you retrieve the book I'd from the authorship.
Try to work out what an author who has not published looks like the. You can use this to formulate the query for the answer you are looking for with an appropriate where clause.
This is a good spot to use the LEFT JOIN antipattern:
SELECT a.*
FROM authors a
LEFT JOIN authorships s ON s.author_id = a.author_id
WHERE s.author_id IS NULL
Rationale: when the LEFT JOIN comes up empty, it means that the author has no corresponding record in the authorships table. The WHERE clause filters out on unmatched authors records only (ie authors that have no books). This is called an antipattern because the purpose of a JOIN is usually to match records, whereas here we use it to detect unmatched records.
Its really easy, just check which column seems to be having common value between all this three tables if something is common atleast within two tables then put inner join on those two and an outer join on the uncommon data table.
Remember your Aliases will always matter when you join between different tables, also the ON and WHERE should be properly mentioned.

SQL INNER JOIN without linked column

I have an UltraGrid displaying customer information in it. The way the database is set up, there are 2 tables. Customers and Customer_Addresses. I need to be able to display all of the columns from Customers as well as Town and Region from Customer_Addresses, but I'm under the impression that I'd need Town and Region columns in the Customer table to be able to do this? I've never used an INNER JOIN before so I'm not sure if this is true or not, so can anybody give me pointers on how to do this, or if I need the matching columns or not?
Does it even require an INNER JOIN, or is there an alternative way to do this?
Below are the design views of both of the tables - Is it possible to display Add4 and Add5 from Customer_Addresses with all of Customers?
As long as you have another key column you can use to link the tables (ex. ID_Column), it is better that you use LEFT JOIN.
Example:
SELECT c.col1, ... , c.colN, a.town, a.region FROM Customers c
LEFT JOIN Customer_Addresses a ON a.ID_Column = c.ID_Column
In order to clarify how JOIN types work, look at this picture:
In our case, using a LEFT JOIN will take all information from the Customers table, along with any found matching (on ID) information from Customer_Addresses table.
First of all you need some column in common in two tables, all what you have to do is:
CREATE TABLE all_things
AS
SELECT * (or columns that you want to have in the new table)
FROM Costumers AS a1
INNER JOIN Customer_Addresses AS a2 ON a1.column_in_common = a2.column_in_common
The point is what kind of join do you want.
If you can continue the process without having information in table Costumers or in table Customer_Addresses maybe you need OUTER JOIN or other kind of JOIN.

Coding Inner Join subquery as field in query

After looking at example after example of both inner joins and subqueries as fields, I'm apparently not getting some aspect, and I would appreciate help please. I am trying to write one query that must, alas, run in MS Access 2007 to talk to an Oracle database. I have to get values from several different places for various bits of data. One of those bits of data is GROUP_CODE (e.g., faculty, staff, student, alum, etc.). Getting that is non-trivial. I am trying to use two inner joins to get the specific value. The value of borrower category must be the value for my main row in the outer query. Here is what this looks like:
Patron table Patron_Barcode table Patron_Group table
Patron_id Barcode Patron_Group_iD
Barcode Patron_Group_id PATRON_Group_Code
I want to get the PATRON_GROUP.PATRON_GROUP_CODE. This is only one of 35 fields I need to get in my query. (Yes, that's terrible, but wearing my librarian hat, i can't write the Java program I'd like to write to do this in a snap.)
So as a test, I wrote this query:
select PATRON.PATRON_ID As thePatron,
(SELECT PATRON_GROUP.PATRON_GROUP_CODE As borrowwerCategory
FROM (PATRON_GROUP
INNER JOIN PATRON_BARCODE ON PATRON_GROUP.PATRON_GROUP_ID = PATRON_BARCODE.PATRON_GROUP_ID
) INNER JOIN PATRON ON PATRON_BARCODE.PATRON_ID = thePatron.PATRON_ID
));
I don't know what I'm doing wrong, but this doesn't work. I've written a fair amount of SQL in my time, but never anything quite like this. What am I doing wrong?
PATRON.BARCODE is the foreign key for the BARCODE table.
PATRON_BARCODE.PATRON_GROUP_ID is the foreign key for the PATRON_GROUP table. PATRON_GROUP_CODE in PATRON_GROUP is he column value that I need.
PATRON.BARCODE -> BARCODE.PATRON_GROUP_ID -> PATRON_GROUP.PATRON_GROUP_CODR>
The main table, PATRON, will have lots of other things, like inner and outer join to PATRON_ADDRESS, etc., and I can't just do an inner join directly to what I want in my main query. This has to happen in a subquery as a field. Thanks.
Ken

How to design the database schema to link two tables via lots of other tables

Although I'm using Rails, this question is more about database design. I have several entities in my database, with the schema a bit like this: http://fishwebby.posterous.com/40423840
If I want to get a list of people and order it by surname, that's no problem. However, if I want to get a list of people, ordered by surname, enrolled in a particular group, I have to use an SQL statement that includes several joins across four tables, something like this:
SELECT group_enrolment.*, person.*
FROM person INNER JOIN member ON person.id = member.person_id
INNER JOIN enrolment ON member.id = enrolment.member_id
INNER JOIN group_enrolment ON enrolment.id = group_enrolment.enrolment_id
WHERE group_enrolment.id = 123
ORDER BY person.surname;
Although this works, it strikes me as a bit inefficient, and potentially as my schema grows, these queries could get more and more complicated.
Another option could be to join the person table to all the other tables in the query by including person_id in the other tables, then it would just be one single join, for example
SELECT group_enrolment.*, person.*
FROM person INNER JOIN group_enrolment ON group_enrolment.person_id
WHERE group_enrolment.id = 123
ORDER BY person.surname;
But this would mean that in my schema, the person table is joined to a lot of other tables. Aside from a complicated schema diagram, does anyone see any disadvantages to this?
I'd be very grateful for any comments on this - whether what I'm doing now (the many table join) or the second solution or another one that hasn't occurred to me is the best way to go.
Many thanks in advance
Well, joins are what databases do. Having said that, you may consider propagating natural keys in your model, which would then allow you to skip over some tables in joins. Take a look at this example.
EDIT
I'm not saying that this will match your model (problem), but just for fun try similar queries on something like this:

When to use JOINs

It seems to me that there are two scenarios in which to use JOINs:
When data would otherwise be duplicated
When data from one query would otherwise be used in another query
Are these scenarios right? Are there any other scenarios in which to use JOIN?
EDIT: I think I've miscommunicated. I understand how a JOIN works, what I'm not so sure about is when to use one.
JOINS are used to JOIN tables together with related information.
Tipical situations are where you have lets say
A user table where the user has specific security settings. The join would be used such that you can determine which settings the user has.
Users
-UserID
-UserName
UserSecurityRoles
-UserID
-SecurityRoleID
SecurityRoles
-SecurityRoleID
-SecurityRole
SELECT *
FROM Users u INNER JOIN
UserSecurityRoles usr ON u.UserID = usr.UserID INNER JOIN
SecurityRoles sr ON usr.SecurityRoleID = sr.SecurityRoleID
WHERE sr.SecurityRole = 'Admin'
LEFT joins will be used in the cases where you wish to retrieve all the data from the table in the left hand side, and only data from the right that match.
JOINS are used when you start normalizing your table structure. You can crete a table with 100s on columns, where a lot of the data could possibly be NULL, or you can normalize the tables, such that you avoid having too many columns with null values, where you group the appropriate data into table structures.
The answer to this Question has a VERY good link that has graphical display of using JOINs
JOINS are used to return data that is related in a relational database. Data can be related in 3 ways
One to Many relationship (A Person can have many Transactions)
Many to Many relationship (A Doctor can have many Patients, but a Patient can have more than one Doctor)
One to One relationship (One Person can have exactly one Passport number)
JOINS come in various flavours:
AN INNER JOIN will return data from both tables where the keys in each table match
A LEFT JOIN or RIGHT JOIN will return all the rows from one table and matching data from the other table
A CROSS JOIN will return the product of each table
You use joins when you need information from more than one table :)