What's wrong with my sql query using left joins? - mysql

I'm using MySQL. I have 3 tables I'm trying to connect in a query and I can't see what I'm doing wrong with the following query:
Table 1: books (list of book information)
Table 2: bookshelf (list of books a member owns)
Table 3: book_reviews (list of book reviews)
I want to generate a list of all books a user has in their bookshelf, as well as any reviews they have made. The following query gives me a list only of books the user has reviewed; I want all of their books. I thought the second LEFT OUTER JOIN would do this - connecting the bookshelf titles to the book reviews titles, but I don't get any books with no reviews (there should be lots). Removing the second JOIN statement (and putting bookshelf in the FROM statement) allows me to get a list of titles with no reviews, but it shows all book reviews by all users.
SELECT books.title, book_reviews.comments
FROM books
LEFT OUTER JOIN book_reviews ON books.ID = book_reviews.book_id
LEFT OUTER JOIN bookshelf ON book_reviews.user_id = bookshelf.user_id
WHERE bookshelf.book_id = books.ID
AND bookshelf.user_id =1
I imagine I'm missing something very obvious, but I've been reading about joins and going over my logic and I'm blind to it. Thanks to anyone who can help me see...

Try this:
SELECT books.title, book_reviews.comments
FROM bookshelf
LEFT OUTER JOIN books ON books.ID = bookshelf.book_id
LEFT OUTER JOIN book_reviews ON book_reviews.book_id = books.ID
AND book_reviews.user_id = bookshelf.user_id
WHERE bookshelf.user_id =1

Related

How to do SQL Join with many tables (FK tables have looped results sharing ID)

I am newish to SQL and Join statements and I am way out of my league at the moment
I currently have 6 Database Tables that are all linked to the main 7th table based on the main tables ID, however all the information in the other 6 tables are looped and so have several displayed results to the one main tables ID.
Is it possible to join them all into one Join Statement so I can have a results so that everyones information from the main table also shows their information from the 6 other linked tables
So basically when they all have the informationed joined I want to be able to Display all information on a webpage
so I was wondering do I need to do multiple JOIN statements or just one Longer one?
I have Included some Images below that explain it visually. See examples 1 and 2
The columns that are highlighted in yellow are looped to have many results:
2. This is the example of how the information is looped into the
database where there are many Race_id sharing to the same inf_id:
Im not so sure how it will look once it has been joined since some of the information is looped into many Id's and not sure if that means it need to duplicate the column or the rows?? any help would be greatly appreciated.
You could use left join eg for the first tables influencer, social, activities
select i.*, s.follower, s.Social_Medial_URL, a.activity, a.result
from influencer i
left join social s on s.inf_id = i.id
left join activities a on a.inf_id = i.id
you can procede yourself adding the left join for the others tables using the same rules
select i.*
, s.follower_count
, s.social_media_url
, a.compete_activity
, a.compete_results
from influencers i
left join inf_other_social s on s.inf_id = i.id
left join inf_compete_activity a on a.inf_id = i.id
LIMIT 0, 25
I think you are confused about primary key and foreign key. the picture you have given is clearly elaborate everything. as per your db diagram the query might be like this...
select * from
Influencer i
Left Join Social s on i.inf_id = s.inf_id
Left Join Owned_Equip o on i.inf_id=o.inf_id
Left Join Ages_Interacted a on i.inf_id = a.inf_id
Left Join Activities ac on i.inf_id = ac.inf_id
Left Join Awards aw on i.inf_id = aw.inf_id
Left Join History h on i.inf_id = h.inf_id
By using this above query you can get all the information of Influencer and related to him (Social,Owned_Equip,Activities,Award etc) whether they exists or not. If you using only "Join" not "Left Join" then you can only find those records which is common for a single influencer to it's related entities/tables which might you say. as an example: say Influencer (id = 1 , suppose name is dan) after inner join we can get only records related to dan ( his social,owned equipments,activites,awards and so on if those tables contains record related to dan record)

MYSQL nested inner join query

I wanted to create a nested query that on the outside gets the title and price from a table called 'Books' while having a nest inside the query that gets the Author's First and last name for that specific book. I'm just a little confused on the Inner Joins and where they need to be placed. This is as close as I was able to get with it but this just prints every author for every book.
select Title, AuthorFirst, AuthorLast,Price from Book
JOIN
(select AuthorLast,AuthorFirst from Author
INNER JOIN Wrote on Author.AuthorNum = Wrote.AuthorNum
INNER JOIN Book on Wrote.BookCode = Book.BookCode group by title desc)Auth;
This joins the tables that I need but it prints every author in the DB with every book in the database. I think it has something with my Inner Joins not being specific enough.
The group by clause is wrong and you should remove it. Once you do that, there's no need to nest the joins - you could just have several joins in the same query:
SELECT Title, AuthorFirst, AuthorLast, Price
FROM Book
INNER JOIN Wrote ON Author.AuthorNum = Wrote.AuthorNum
INNER JOIN Book ON Wrote.BookCode = Book.BookCode

How can i get book's title and author's firstname into the same result table when my database is designed like this

I have 3 tables
1. titles table have 2 fields(title,isbn)
2. authorisbn table have 2 fields(authorid,isbn)
3. authors table have 2 fields(authorid,firstname)
so i want to get a book's title(where the title is like '%Java%') and author's firstname of that book to fill in the same result table
what is the sql statement should i have to use to achieve that
my sql statement is like this
select titles.title, titles.isbn, authorisbn.authorid
from titles inner join authorisbn
where title like '%Java%' and authorisbn.isbn = titles.isbn
but it does not work because i can get only authorid
sorry for my english im learning it as well
I think this is your answer:
select v1.title, v1.isbn,authorisbn.authorid, authors.firstname
FROM books v1
INNER join authorisbn
ON v1.isbn = authorisbn.isbn
INNER JOIN books v2
on v2.isbn = authorisbn.isbn
INNER JOIN authors
WHERE v2.title like '%Java%';
Here, v1 and v2 are representing the books table, but when we use it multiple times in our query we should define them in new variables.
If this helps, please check it as an answer
try this.
select titles.title, titles.isbn, authorisbn.authorid, authors.firstname
from authorisbn
left join titles on titles.isbn = authorisbn.isbn
left join authors on authors.authorid = authorisbn.authorid
where titles.title like '%Java%'
you need to get to the authors table to get authors.firstname
select titles.title, titles.isbn, authorisbn.authorid, authors.firstname
from titles
inner join authorisbn
on authorisbn.isbn = titles.isbn
and title like '%Java%'
inner join authors
on authors.authorid = authorisbn .authorid
can move title like '%Java%' down into a where clause
where title like '%Java%'

MySQL: how to get result from 2 tables without repeating results?

I've got 3 tables: book, publisher, book_category
For a particular book category (fantasy) I have to display list of publisher names supplying that genre.
publisher_name and category_name are linked through book table, so my query is:
SELECT publisher.publisher_name
FROM publisher, book, book_category
WHERE publisher.publisher_id = book.publisher_id
AND book.category_id = book_category.category_id
AND category_name = 'fantasy';
But the result I'm getting is repeating the name of publisher if there's more than one fantasy book supplied by that publisher.
Let's say I've got The Hobbit and The Lord of the Rings,both are fantasy and are supplied by the same PublisherA.
In that case the result of my query is:
PublisherA
PublisherA
Is it possible to get that result just once? Even if there's much more than 2 fantasy books
published by the same publisher?
Just use distinct if you only need publisher_name
SELECT distinct publisher.publisher_name
by the way, try to use JOIN syntax... to join tables
SELECT distinct p.publisher_name
FROM publisher p
join book b on b.publisher_id = p.publisher_id
join book_Category bc on bc.category_id = b.category_id
where bc.category_name = 'fantasy'
Use DISTINCT
SELECT DISTINCT publisher.publisher_name
FROM publisher, book, book_category
WHERE publisher.publisher_id = book.publisher_id
AND book.category_id = book_category.category_id
AND category_name = 'fantasy';
Try adding this to the end of the query: GROUP BY publisher.publisher_name
Everyone is mentioning DISTINCT, which is correct (better than GROUP BY in MySQL, because of the way the optimizer is set up), but I figured I would also add a modification for performance enhancements.
Currently you have implicit cross joins to get to the other tables, and making these explicit INNER JOINs will increase efficiency because of the order of filtering. Example:
SELECT DISTINCT Publisher.publisher_name
FROM publisher Publisher
INNER JOIN book Book ON Publisher.publisher_id = Book.publisher_id
INNER JOIN book_category Book_Category ON Book.category_id = Book_Category.category_id
WHERE Book_Category.category_name = 'fantasy';
In the original query, you bring in the complete record set of all three tables (publisher, book, book_category), and then from that set you join on the respective keys, and then return the result set. In this new query, your join to Book_Category happens based only upon the record set returned from the join between Publisher and Book. If there is filtering that happens based on this join, you will see a performance increase.
You also have the added benefit of being ANSI-compliant, as well as explicit coding to improve ease of maintenance.

MySQL calling in Username to show instead of ID?

I have a users table, books table and authors table. An author can have many books, while a user can also have many books. (This is how my DB is currently setup). As I'm pretty new to So far my setup is like bookview.php?book_id=23 from accessing authors page, then seeing all books for the author. The single book's details are all displayed on this new page...I can get the output to display the user ID associated with the book, but not the user name, and this also applies for the author's name, I can the author ID to display, but not the name, so somewhere in the query below I am not calling in the correct values:
SELECT users.user_id,
authors.author_id,
books.book_id,
books.bookname,
books.bookprice,
books.bookplot
FROM books
INNER JOIN authors on books.book_id = authors.book_id
INNER JOIN users ON books.book_id = users.user_id
WHERE books.book_id=" . $book_id;
Could someone help me correct this so I can display the author name and user name both associated with the book! Thanks for the help :)
I think the right join conditions would be something like (changes bolded)
SELECT users.user_id,
**users.user_name,**
authors.author_id,
**authors.author_name,**
books.book_id,
books.bookname,
books.bookprice,
books.bookplot
FROM books
INNER JOIN authors on books.**author_id** = authors.**author_id**
INNER JOIN users ON books.**user_id** = users.user_id
WHERE books.book_id=" . $book_id;
Or you can use the less verbose syntax for simple inner joins.
SELECT users.user_id,
users.user_name,
authors.author_id,
authors.author_name,
books.book_id,
books.bookname,
books.bookprice,
books.bookplot
FROM books, authors, users
where books.author_id = authors.author_id
and books.user_id = users.user_id
and books.book_id=" . $book_id
It would help if I added the name fields into the select query :D
These two joins together:
INNER JOIN authors on books.book_id = authors.book_id
INNER JOIN users ON books.book_id = users.user_id
also imply authors.book_id = users.user_id which, on the face of it, makes no sense. Surely the code you've posted is not the code you're actually using...?