Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Join If Exists in a MySQL query

Tags:

sql

join

mysql

I'm running a report that exports the information for members of committees into an excel spreadsheet.

Here's my query:

SELECT membership_organization.name AS Firm, 
membership_individual.first AS FirstName, 
membership_individual.middle AS MiddleName, 
membership_individual.last AS LastName, 
membership_individual.email AS Email, 
membership_individual.phone AS Phone, 
membership_location.addr1 AS Address1, 
membership_location.addr2 AS Address2, 
membership_location.city AS City, 
membership_location.state AS State, 
membership_location.zipcode AS Zip 
FROM membership_individual 
JOIN membership_organization ON membership_individual.org_name_id = membership_organization.id 
JOIN membership_location ON membership_individual.location_id = membership_location.id 
WHERE membership_individual.id IN ({list if ids}) 
ORDER BY LastName

The problem is some of the members don't have a location id set, or it's set to 0, so those members don't show up in the report.

Is there a way I can qualify the location JOIN? If the members location id exists pull the info, if not show me the info that is available.

like image 628
Ryan Avatar asked Jun 08 '11 13:06

Ryan


People also ask

Can we add a condition on join?

To use the WHERE clause to perform the same join as you perform using the INNER JOIN syntax, enter both the join condition and the additional selection condition in the WHERE clause. The tables to be joined are listed in the FROM clause, separated by commas. This query returns the same output as the previous example.

Which is faster exists or join?

Most of the time, IN and EXISTS give you the same results with the same performance. On the other hand, when you use JOINS you might not get the same result set as in the IN and the EXISTS clauses. So, to optimize performance, you need to be smart in using and selecting which one of the operators.

WHERE exists vs LEFT join?

EXISTS and NOT EXISTS both short circuit - as soon as a record matches the criteria it's either included or filtered out and the optimizer moves on to the next record. LEFT JOIN will join ALL RECORDS regardless of whether they match or not, then filter out all non-matching records.


3 Answers

Change both of your JOINs into LEFT JOINs. You'll get all your records from membership_individual where the where clause matches, and NULL values for the other tables where rows don't match.

like image 83
Fosco Avatar answered Oct 19 '22 22:10

Fosco


Use a LEFT OUTER JOIN:

SELECT membership_organization.name AS Firm, 
membership_individual.first AS FirstName, 
membership_individual.middle AS MiddleName, 
membership_individual.last AS LastName, 
membership_individual.email AS Email, 
membership_individual.phone AS Phone, 
membership_location.addr1 AS Address1, 
membership_location.addr2 AS Address2, 
membership_location.city AS City, 
membership_location.state AS State, 
membership_location.zipcode AS Zip 
FROM membership_individual 
JOIN membership_organization ON membership_individual.org_name_id = membership_organization.id 
LEFT OUTER JOIN membership_location ON membership_individual.location_id = membership_location.id 
WHERE membership_individual.id IN ({list if ids}) 
ORDER BY LastName
like image 39
Frank Schmitt Avatar answered Oct 20 '22 00:10

Frank Schmitt


Use left join, meaning your query will become

SELECT membership_organization.name AS Firm, 
membership_individual.first AS FirstName, 
membership_individual.middle AS MiddleName, 
membership_individual.last AS LastName, 
membership_individual.email AS Email, 
membership_individual.phone AS Phone, 
membership_location.addr1 AS Address1, 
membership_location.addr2 AS Address2, 
membership_location.city AS City, 
membership_location.state AS State, 
membership_location.zipcode AS Zip 
FROM membership_individual 
JOIN membership_organization ON membership_individual.org_name_id = membership_organization.id 
LEFT JOIN membership_location ON membership_individual.location_id = membership_location.id 
WHERE membership_individual.id IN ({list if ids}) 
ORDER BY LastName

and you'll get the data for all members, even the ones for whom there are no rows in the location table.

like image 27
Nikoloff Avatar answered Oct 19 '22 22:10

Nikoloff