How to include a full column using a join - mysql

I'm doing an homework assignment and I have most of it but I can't get the last part. I don't know how to "Include artists without albums in your listing"?
SELECT
artist.name, Title
FROM
artist
INNER JOIN
album ON artist.artistID = album.artistid
ORDER BY
name, title;
This is what I get (top) and what I'm supposed to get (bottom):

You need to use LEFT JOIN instead of INNER JOIN in this case.
Different joins explanation with examples could be found in many places, for example in wikipedia

Related

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

complex sql-query for movie listing

I have a database with all movies I've seen in the cinema. it consists of a couple of tables:
screenings (main table with, date, cinema, movie, etc.)
movies (all information about the movies: title, director, length...)
cinemas (information about the cinema I watched it in, not used in my example)
tags (tags connected to movies fields: id, tag)
tag_scr (link table links tags to screenings, fields: scr_id, tag_id)
Most screenings have one tag connected (can be stuff like, film festival, 3d, premiere, live music) but screenings can also have zero tags or more than one, so what I'm trying to do is to create a query where I list all screenings, and all of the tags connected to that screening concatenated to a string with comas between. My query looks like this now:
SELECT screenings.id, movies.title, tags.tag FROM screenings
JOIN movies ON screenings.ft = movies.id
LEFT JOIN tag_scr ON screenings.id = tag_scr.scr_id
LEFT JOIN tags ON tag_scr.tag_id = tags.id
And that does what I need except the screenings with multiple tags are listed multiple times in the result. And if I group by screenings.id I only get the first tag on each screening. Is it possible to do what I want, using the concat function, a sub-query or any other method? My database is MySQL 5.5.24.
Yep, you need to use GROUP_CONCAT:
SELECT screenings.id, movies.title, GROUP_CONCAT(tags.tag SEPARATOR ',') tags
FROM screenings
JOIN movies ON screenings.ft = movies.id
LEFT JOIN tag_scr ON screenings.id = tag_scr.scr_id
LEFT JOIN tags ON tag_scr.tag_id = tags.id
GROUP BY screenings.id, movies.title
You don't really need the SEPARATOR syntax as by default, it's a comma.
http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html#function_group-concat
Good luck.

MySQL join that shows members of table a that are empty in table b but not vice versa

I'm sure this has been asked before, and I apologize for asking it again, but I've done some searching probably for the wrong terms and just haven't been able to find the right approach.
I have two tables. Websites is a list of web sites (id | website), cdd is a list of users and the site they were referred from (userid | website | etc..). Not every site that referred users is a sponsor, and thus in the websites table. Also, not every site that is a sponsor has sent us users. I need a list of the number of users from each sponsor, including the 0s.
This is the query I have so far:
SELECT w.website, COUNT(*) AS num FROM websites w LEFT JOIN cdd c ON w.website = c.website WHERE c.submitted LIKE '05/26/11 %' GROUP BY w.website ORDER BY num DESC;
There are five sites in the website table, but one has not sent any users. That one does not show up in the queries.
Any thoughts?
The LEFT JOIN is correct, but because you are specifying a WHERE clause against the table (cdd) on the right side of the join, you are filtering out websites that have no associated cdd record. You need to specify that criterion like so:
[...]
FROM websites w
LEFT JOIN cdd c ON w.website = c.website
WHERE c.submitted IS NULL OR c.submitted LIKE '05/26/11 %'
[...]
which includes the websites that don't join to any cdd record, or
[...]
FROM websites w
LEFT JOIN cdd c ON w.website = c.website AND c.submitted LIKE '05/26/11 %' 'Replaces WHERE clause
[...]
which includes all websites, but only joins to cdds with the matching submitted date.
Note: To ensure that sites with no associated users return a count of 0, you may also need to COUNT() a column from cdd, rather than *...
I need a list of the number of users from each sponsor, including the 0s.
In that case you probably should be using a left join:
SELECT a.site, COUNT(b.ref_site) AS num FROM table1 a LEFT JOIN table2 b ON a.site = b.ref_site GROUP BY a.site;
Make the INNER JOIN a LEFT JOIN instead and I think you're good to go.
SELECT a.site, COUNT(b.ref_site) AS num
FROM table1 a
LEFT JOIN table2 b
ON a.site = b.ref_site
GROUP BY a.site;

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

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

MySQL Multiple Left Joins

I am trying to create a news page for a website I am working on. I decided that I want to use correct MySQL queries (meaning COUNT(id) and joins instead of more than one query or num_rows.) I'm using a PDO wrapper, that should function fine, and this still fails when run directly through the MySQL CLI application.
Basically, I have 3 tables. One holds the news, one holds the comments and one holds the users. My aim here is to create a page which displays all (will paginate later) the news posts titles, bodies, authors and dates. This worked fine when I used a second query to get the username, but then I decided I'd rather use a JOIN.
So what's the problem? Well, I need two joins. One is to get the author's username and the other to get the number of comments. When I simply go for the author's username, all works as expected. All the rows (there are 2) in the news table are displayed. However, when I added this second LEFT JOIN for the comments row, I end up only receiving one row from news (remember, there are 2,) and COUNT(comments.id) gives me 2 (it should display 1, as I have a comment for each post.)
What am I doing wrong? Why is it only displaying one news post, and saying that it has two comments, when there are two news posts, each with one comment?
SELECT news.id, users.username, news.title, news.date, news.body, COUNT(comments.id)
FROM news
LEFT JOIN users
ON news.user_id = users.id
LEFT JOIN comments
ON comments.news_id = news.id
Also, just to be sure about one other thing, my left join to comments is the correct way to get all posts regardless of whether they have comments or not, correct? Or would that be a right join? Oh, one last thing... if I switch comments.news_id = news.id to news.id = comments.news_id, I get 0 results.
You're missing a GROUP BY clause:
SELECT news.id, users.username, news.title, news.date, news.body, COUNT(comments.id)
FROM news
LEFT JOIN users
ON news.user_id = users.id
LEFT JOIN comments
ON comments.news_id = news.id
GROUP BY news.id
The left join is correct. If you used an INNER or RIGHT JOIN then you wouldn't get news items that didn't have comments.
To display the all details for each news post title ie. "news.id" which is the primary key, you need to use GROUP BY clause for "news.id"
SELECT news.id, users.username, news.title, news.date,
news.body, COUNT(comments.id)
FROM news
LEFT JOIN users
ON news.user_id = users.id
LEFT JOIN comments
ON comments.news_id = news.id
GROUP BY news.id