Learning LEFT JOIN in MySQL - mysql

dear all.i newbie at web programming and until now i still have learn about MySQL syntax.
for now i start to use LEFT JOIN method. i know that this method use for make normalization between two or many tables. I have posted a question in SO, then I receive an Answer which make me confuse. I have modified that answer,but i still confuse because it use LEFT JOIN just for one table. whether the LEFT JOIN can be used in one table?

You can LEFT JOIN a table with itself, just like you can JOIN a table with itself. Your purpose will usually be different, because the specific characteristic of a LEFT JOIN is ensuring a row in the output when no corresponding row exists on the right, of course; you can select those rows which have specifically been selected that way by checking for NULL for the "other part" of the row, the part that would normally come from the right-side table.
Consider for example a table Product with columns ID, primary key, Name, Category, and Cost; you want info about products that are cheapest in their category. Then...:
SELECT P1.Name, P1.Category, P1.Cost
FROM Product AS P1
LEFT JOIN Product AS P2
ON (P1.Category = P2.Category and P1.Cost > P2.Cost)
WHERE P2.ID IS NULL
is an example of a "left join of a table to itself" which will answer the "you want" spec (if more than one item has the equal-lowest cost in a category you'll get them all -- the query actually gives you the items such that no item in their category is cheaper and has no checks for items of equal cost;-).

Related

Difference between FROM and JOIN tables

I'm working through the JOIN tutorial on SQL zoo.
Let's say I'm about to execute the code below:
SELECT a.stadium, COUNT(g.matchid)
FROM game a
JOIN goal g
ON g.matchid = a.id
GROUP BY a.stadium
As it happens, it produces the same output as the code below:
SELECT a.stadium, COUNT(g.matchid)
FROM goal g
JOIN game a
ON g.matchid = a.id
GROUP BY a.stadium
So then, when does it matter which table you assign at FROM and which one you assign at JOIN?
When you are using an INNER JOIN like you are here, the order doesn't matter. That is because you are connecting two tables on a common index, so the order in which you use them is up to you. You should pick an order that is most logical to you, and easiest to read. A habit of mine is to put the table I'm selecting from first. In your case, you're selecting information about a stadium, which comes from the game table, so my preference would be to put that first.
In other joins, however, such as LEFT OUTER JOIN and RIGHT OUTER JOIN the order will matter. That is because these joins will select all rows from one table. Consider for example I have a table for Students and a table for Projects. They can exist independently, some students may have an associated project, but not all will.
If I want to get all students and project information while still seeing students without projects, I need a LEFT JOIN:
SELECT s.name, p.project
FROM student s
LEFT JOIN project p ON p.student_id = s.id;
Note here, that the LEFT JOIN refers to the table in the FROM clause, so that means ALL of students were being selected. This also means that p.project will be null for some rows. Order matters here.
If I took the same concept with a RIGHT JOIN, it will select all rows from the table in the join clause. So if I changed the query to this:
SELECT s.name, p.project
FROM student s
RIGHT JOIN project p ON p.student_id = s.id;
This will return all rows from the project table, regardless of whether or not it has a match for students. This means that in some rows, s.name will be null. Similar to the first example, because I've made project the outer joined table, p.project will never be null (assuming it isn't in the original table). In the first example, s.name should never be null.
In the case of outer joins, order will matter. Thankfully, you can think intuitively with LEFT and RIGHT joins. A left join will return all rows in the table to the left of that statement, while a right join returns all rows from the right of that statement. Take this as a rule of thumb, but be careful. You might want to develop a pattern to be consistent with yourself, as I mentioned earlier, so these queries are easier for you to understand later on.
When you only JOIN 2 tables, usually the order does not matter: MySQL scans the tables in the optimal order.
When you scan more than 2 tables, the order could matter:
SELECT ...
FROM a
JOIN b ON ...
JOIN c ON ...
Also, MySQL tries to scan the tables in the fastest way (large tables first). But if a join is slow, it is possible that MySQL is scanning them in a non-optimal order. You can verify this with EXPLAIN. In this case, you can force the join order by adding the STRAIGHT_JOIN keyword.
The order doesn't always matter, I usually just order it in a way that makes sense to someone reading your query.
Sometime order does matter. Try it with LEFT JOIN and RIGHT JOIN.
In this instance you are using an INNER JOIN, if you're expecting a match on a common ID or foreign key, it probably doesn't matter too much.
You would however need to specify the tables the correct way round if you were performing an OUTER JOIN, as not all records in this type of join are guaranteed to match via the same field.
yes, it will matter when you will user another join LEFT JOIN, RIGHT JOIN
currently You are using NATURAL JOIN that is return all tables related data, if JOIN table row not match then it will exclude row from result
If you use LEFT / RIGHT {OUTER} join then result will be different, follow this link for more detail

SQL - Joining tables BUT not always

I need to perform a query SELECT that joins three tables (no problem with that). Nonetheless, the third table can, or NOT, have any element that match the joining KEY.
I want ALL data from the first two tables and if the ITEMS have ALSO information in the third table, fetch this data to.
For example, imagine that the first table have a person, the second table have his/her address (everyone lives anywhere), the third table stores the driving license (not everyone has this) - but I need to fetch all data whether or not people (all people) have driving license.
Thanks a lot for reading, if possible to give you suggestion / solution!
Use LEFT JOIN to join the third table. Using INNER JOIN a row has to exists. Using LEFT JOIN, the 'gaps' will be filled with NULLs.
SELECT
p.PersonID, -- NOT NULL
-- dl.PersonID, -- Can be null. Don't use this one.
p.FirstName,
p.LastName,
a.City,
a.Street,
dl.ValidUntilDate
FROM
Person p
INNER JOIN Addresse a ON a.AddressID = p.HomeAddressID
LEFT JOIN DrivingLicence dl ON dl.PersonId = p.PersonID

Join of tables returning incorrect results

There are 4 sql tables:
Listings(Amount, GroupKey, Key, MemberKey),
Loans(Amount, GroupKey, Key, ListingKey),
Members(City, GroupKey, Key)
Groups(GroupRank, Key, MemberKey)
Now, if one wants to find out the loans which are also listings and find the members city and GroupRank for the members in the loan table. Here, the group table contains information about grous of which members are a part of.
and also perform a select operation as given below:
select Listings.Amount, Members.City, Groups.GroupRank
from listings, loans, members, groups
where Listings.Key=Loans.ListingKey and
Members.Key=Listings.MemberKey and
Listings.GroupKey=Groups.Key
The above join is giving an incorrect result, please point out where I am going wrong.
Also I am new to SQL so please excuse the novice question.
Note: The following is just a guess what your problem is. Like others said, clearify your question.
You want to JOIN
( http://dev.mysql.com/doc/refman/5.1/de/join.html )
those tables. What you write is just another form of a join, meaning it has the same effect. But you "joined" a bit too much. To make things clearer a syntax has been invented to make things clearer and avoid such mistakes. Read more about it in the link given above.
What you want to achieve can be done like this:
SELECT
Listings.Amount, Members.City, Groups.GroupRank
FROM
Listings
INNER JOIN Groups ON Listings.GroupKey=Groups.Key
INNER JOIN Members ON Members.Key=Listings.MemberKey
You don't do a SELECT on the Loans table, you don't need it in this query.
This is the INNER JOIN which will give you a result where every row in table A has an according entry in table B. When this is not the case, you have to use the LEFT or RIGHT JOIN.
Maybe the problem is related to the join type (INNER). Try LEFT JOIN for example but Mark has right: you should clearify your question.
I would firstly change your query to use the more modern join syntax, which allows outer joins. Tr this:
select Listings.Amount, Members.City, Groups.GroupRank
from listings
left join loans on Listings.Key=Loans.ListingKey
left join members on Members.Key=Listings.MemberKey
left join groups on Listings.GroupKey=Groups.Key
and/or Loans.GroupKey=Groups.Key
and/or Members.Key=Groups.MemberKey
You may need to play with the criteria on the last join (maybe they should be "or" not "and" etc).

MySQL one to many data relationship with added complications

I have a database in which there are multiple posts. Each post can be associated with one or more location. Each location is then associated with one country.
This is handled through four tables:
post (with the id and post_title)
postlocation (with the fields post_id and location_id - to allow a one to many relationship)
location (with the fields id, location_title and country_id)
country (with the fields, id and country_title)
I want to perform a simple, effective select to retrieve a list of posts and each one's associated locations and each of those locations' country.
I'm at a loss as to how to best achieve this, and any help would be most welcome. Thank you.
Use LEFT JOIN:
SELECT post.*, location.*, country.*
FROM post
LEFT JOIN postlocation ON post.id = postlocation.post_id
LEFT JOIN location ON postlocation.location_id = location.id
LEFT JOIN country ON location.country_id = country.id
Here's an explanation of how LEFT JOIN works: http://www.mysqltutorial.org/mysql-left-join.aspx
The MySQL LEFT JOIN clause works like this: when a row from the left
table matches a row from the right table based on join_condition, the
row’s content are selected as an output row. When row in the left
table has no match it is still selected for output, but combined with
a “fake” row from the right table that contains NULL in all columns.
In short, the MySQL LEFT JOIN clause allows you to select all rows
from the left table even there is no match for them in the right
table.
When you have multiple LEFT JOINs, then in each case it uses the cumulative results so far as the "left" table and the table your are joining on as the "right" table.
So the query above will return one row for every post/location/country. Note that this means there will be potentially several rows with the same post.* data (one for each postlocation associated with taht post).
And if a post has no postlocations associated with it, that post will still show up in the results (but with null rows for location.* and country.*). Similarly, if a location has no country associated it with it, the post/location rows will still show up in the output (but with null rows for country.*). This is the advantage of LEFT JOIN -- you always get all the rows from the table on the "left".

Please explain MySQL Joins in simple language

Please explain to me joins in simple language. Please do not post a web link as I need to read how a developer understand it, not an author.
Best I can point you to is A Visual Explanation of SQL Joins.
The diagrams helped me a lot.
Adding the main diagrams from the linked post here.
Inner Join
Inner join produces only the set of records that match in both Table A and Table B.
Full outer join
Full outer join produces the set of all records in Table A and Table B, with matching records from both sides where available. If there is no match, the missing side will contain null.
Left outer join
Left outer join produces a complete set of records from Table A, with the matching records (where available) in Table B. If there is no match, the right side will contain null.
Given Table Person And Information
SELECT *
FROM Person INNER JOIN
Information ON Person.ID = Information.ID
Will only return rows from both tables where both tables have the same IDs. So only if the ID exists in both Person and Information will the row be returned.
SELECT *
FROM Person LEFT JOIN
Information ON Person.ID = Information.ID
Will return all rows from Person, and only those that match from Information, where it does not match, it will return NULLs
SELECT *
FROM Person LEFT JOIN
Information ON Person.ID = Information.ID
WHERE Information.ID IS NULL
Will return all rows from Person that DOES NOT HAVE an entry in Information. This shows you the list of persons that do not have their Informaton updated yet.
I'm interpreting your question to mean joins in a very general sense, not each type of join, so if this is off the mark then I apologize:
Basically, joins enable you to get data from multiple tables in a single query by adding columns to your result set. So if you had the following tables:
Books (ID, Title, AuthorID)
Authors (ID, Name)
You could get a result set that looked like this:
Book | Author
'The Sirens of Titan' | 'Kurt Vonnegut'
'The Old Man and the Sea' | 'Earnest Hemingway'
By joining the two tables together like so:
select Books.Title as Book, Authors.Name as Author
from Books
inner join Authors on Authors.ID = Books.AuthorID
An inner join is the simplest type of join; it may be difficult to understand the point of outer joins without first having a strong grasp of inner joins and their uses.