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.
Related
I have three tables: Member, Meeting and Member_Meeting. The names alone should give away what they contain. Member is for registered members, Meeting is for past and future meetings and Member_Meeting is for members who have or will be attending meetings. I can use inner joins to get data in both tables, left joins to get data in both but also on the left, right joins to get data in both but also on the right and (full) outer joins to get data from both and right and left. What I need however is data that only exists in Member but not in Member_Meeting. In other words, I need to get all the members that exist but have not ever attended a meeting and therefore do not have a record in the Member_Meeting. What I need is sort of like a left join or a right join but without what the tables have in common.
There's two ways of doing this. The first is to do a subquery using NOT IN():
SELECT * FROM Member WHERE ID NOT IN(SELECT DISTINCT MemebrID FROM Member_Meeting)
The other option is to do a LEFT JOIN and then filter on the null values
SELECT Member.* FROM Member
LEFT JOIN Member_Meeting ON Member.ID = Member_Meeting.MemberID
WHERE Member_Meeting.MemberID IS NULL
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
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).
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;-).
MySQL setup: step by step.
programs -> linked to --> speakers (by program_id)
At this point, it's easy for me to query all the data:
SELECT *
FROM programs
JOIN speakers on programs.program_id = speakers.program_id
Nice and easy.
The trick for me is this. My speakers table is also linked to a third table, "books." So in the "speakers" table, I have "book_id" and in the "books" table, the book_id is linked to a name.
I've tried this (including a WHERE you'll notice):
SELECT *
FROM programs
JOIN speakers on programs.program_id = speakers.program_id
JOIN books on speakers.book_id = books.book_id
WHERE programs.category_id = 1
LIMIT 5
No results.
My questions:
What am I doing wrong?
What's the most efficient way to make this query?
Basically, I want to get back all the programs data and the books data, but instead of the book_id, I need it to come back as the book name (from the 3rd table).
Thanks in advance for your help.
UPDATE:
(rather than opening a brand new question)
The left join worked for me. However, I have a new problem. Multiple books can be assigned to a single speaker.
Using the left join, returns two rows!! What do I need to add to return only a single row, but separate the two books.
is there any chance that the books table doesn't have any matching columns for speakers.book_id?
Try using a left join which will still return the program/speaker combinations, even if there are no matches in books.
SELECT *
FROM programs
JOIN speakers on programs.program_id = speakers.program_id
LEFT JOIN books on speakers.book_id = books.book_id
WHERE programs.category_id = 1
LIMIT 5
Btw, could you post the table schemas for all tables involved, and exactly what output (or reasonable representation) you'd expect to get?
Edit: Response to op author comment
you can use group by and group_concat to put all the books on one row.
e.g.
SELECT speakers.speaker_id,
speakers.speaker_name,
programs.program_id,
programs.program_name,
group_concat(books.book_name)
FROM programs
JOIN speakers on programs.program_id = speakers.program_id
LEFT JOIN books on speakers.book_id = books.book_id
WHERE programs.category_id = 1
GROUP BY speakers.id
LIMIT 5
Note: since I don't know the exact column names, these may be off
That's typically efficient. There is some kind of assumption you are making that isn't true. Do your speakers have books assigned? If they don't that last JOIN should be a LEFT JOIN.
This kind of query is typically pretty efficient, since you almost certainly have primary keys as indexes. The main issue would be whether your indexes are covering (which is more likely to occur if you don't use SELECT *, but instead select only the columns you need).