MySQL: How to count references to references to a table? - mysql

Say I have a database of publishers, who employ authors, who write books.
Or to phrase it another way, each book, is written by an author, who works for a publisher.
publishers: id
authors: id, publisher_id
books: id, author_id
I know how to get a list of publishers with how many authors each employs, from this question.
How do I get a list of publishers with how many books each has published?
How can I get both - publishers, each with number of authors and number of books?

try this
SELECT COUNT(DISTINCT b.`id`) noofbooks,COUNT(DISTINCT au.id) noofauthers,pub.id publisher FROM publisher pub
INNER JOIN auther au ON au.`pub_id`= pub.`id`
INNER JOIN books b ON b.`aut_id` = au.`id` GROUP BY pub.id

You need a three table join
SELECT publisher.id, count(*) from publisher
INNER JOIN author on publisher.id = author.publisher_id
INNER JOIN book on author.id = book.author_id GROUP BY publisher.id;

You just need to fire a simple sql join query for that like as follow.
SELECT p.publishers , COUNT(a.authors) totalAuthors, COUNT(b.books) TotalBooks
FROM publishers AS p,authors AS a ,books AS b
WHERE p.publishersid = a.publishersid
AND a.authorsid = b.authorsid
GROUP BY p.publishersid;

I ended up with something similar to bhanu's answer:
SELECT publishers.*,
COUNT(DISTINCT authors.id) AS 'author_count',
COUNT(DISTINCT books.id) AS 'book_count'
FROM publishers
LEFT JOIN authors ON (authors.publisher_id = publishers.id)
LEFT JOIN books ON (books.author_id = authors.id)
GROUP BY publishers.id;

Related

MySQL query: Trying to join likes

OBJECTIVE: Want to show books, book like count, authors, and author like count.
-- books: start
SELECT * FROM books
-- likes: get like count of books
JOIN likes ON likes.id = books.likes_id
-- merge table: join to book
JOIN authors_books ON books.id = authors_books.book_id
-- authors: join merge table
JOIN authors ON authors.id = authors_books.author_id
-- likes: get like count of authors
JOIN ????????
I'm stuck at authors likes.
Instead of likes_id:
I would like likes_count (see RESULTS GRID image).
I tried:
JOIN likes AS l2 ON likes.id = authors.likes_id
No luck. Shows all the correct column info at the top, but blank output.
You have to join with likes twice, once for the book, another for the author.
Since you join with the same table, you need to give them aliases to distinguish them.
SELECT books.id, books.title, books.pages, book_likes.count AS book_likes,
authors.first_name, author.last_name, author_likes.count AS author_likes
FROM books
JOIN likes AS book_likes ON book_likes.id = books.likes_id
JOIN authors_books ON books.id = authors_books.book_id
JOIN authors ON authors.id = authors_books.author_id
JOIN likes AS author_likes ON author_likes.id = authors.likes_id

Will this MySQL quearly select all of the authors who wrote a book?

I am haveing a lot of trouble trying to work out this question
Write a query to show the number of authors who have written a book
Author(AuthorID, AuthorName, Address, TelephoneNo, PublisherCode)
Book (BookID, Name, ReleaseDate, Price, AuthorID)
I have
SELECT a.AuthorName, COUNT(b.*) AS ‘number of books written’
FROM Author a JOIN Book b ON a.AuthorID = b.BookID
GROUP BY a.AuthorName;
Which counts the number of books each author has written.
This is not the correct I know, but I can not figure it out??
Assuming the requirement is to count authors that have at least one book, the simplest query to satisfy that would be:
SELECT COUNT(DISTINCT b.authorid)
FROM book b
We probably want to assign an alias (name) to the returned column:
SELECT COUNT(DISTINCT b.authorid) AS `count_of_authors_who_have_at_least_one_book`
FROM book b
We could also do a join to the author table, but that isn't necessary here, unless there are values of authorid in the book table that don't appear in the author table (i.e. there's not a foreign key constraint, or referential integrity is not enforced)
Queries to get authors that have two or more books would be a bit more complicated:
SELECT COUNT(*)
FROM ( -- authors of two or more books
SELECT b.authorid
FROM book b
GROUP
BY b.authorid
HAVING COUNT(1) >= 2
) c
If we want authors that have EXACTLY one book (not two or more) we can tweak the condition in the HAVING clause:
SELECT COUNT(*) AS `count_authors_of_exactly_one_book`
FROM ( -- authors of exactly one book
SELECT b.authorid
FROM book b
GROUP
BY b.authorid
HAVING COUNT(1) = 1
) c
You were pretty close. You need to join on the author ID. You are currently mixing the author and book ID's, which won't match correctly.
SELECT
a.AuthorName,
COUNT(b.*) AS ‘number of books written’
FROM Author a
JOIN Book b ON a.AuthorID = b.AuthorID
GROUP BY a.AuthorName;
If you wanna get just a number that indicate total count of Author that wrote at least on book use below query
select count(*) as author_count from Author where exists (select 1 from Book where Book.AuthorID = Author.AuthorID)

MYSQL: Select Query with multiple values from one column

i am currently working with a MYSQL-Database whichhas three tables:
Books, Keywords and KeywordAssignment.
The tables Books and Keywords are in a many to many relationship therefore the table KeywordAssignment.
Now to my question: I want to search for a book with multiple (max: up to ten) keywords.
I've already tried a self join:
SELECT BookID
FROM Keywords K1 INNER JOIN
Keywords K2
ON K1.KeywordAssignmentID=K2.KeywordAssignmentID INNER JOIN
KeywordAssignment
ON KeywordAssignment.KeywordAssignmentID=K1.KeywordAssignmentID INNER JOIN
Books
ON KeywordAssignment.BookID=Books.BookID
WHERE K1.Keyword='Magic' AND K2.Keyword='Fantasy'
The problem is it only works if the given Keyword are in the right order. If they aren't there are more than one.
I appreciate your help thank you very much!
You need to GROUP BY BookID and a HAVING clause with the condition that both keywords are linked to that BookID:
SELECT b.BookID, b.Title
FROM Books b
INNER JOIN KeywordAssignment ka ON ka.BookID = b.BookID
INNER JOIN Keyword k ON k.KeywordID = ka.KeywordID
WHERE k.Keyword IN ('Magic', 'Fantasy')
GROUP BY b.BookID, b.Title
HAVING COUNT(DISTINCT k.Keyword) = 2
This code will return books that are linked to both 'Magic' and 'Fantasy'.
If you want either of the 2 keywords then remove the HAVING clause.
If I understand your question correctly, you want to query for books that have multiple key words. The key word there is have. I don't have MYSQL but the query should look something like this:
SELECT B.BookID, COUNT(*) as NumberOfKeywords FROM Books B
INNER JOIN KeywordAssignment KA
ON B.BookID = KA.BookID
INNER JOIN Keywords K
ON KA.KeywordID = K.KeywordID
GROUP BY B.BookID
HAVING NumberOfKeywords > 0 AND NumberOfKeywords <= 10
What we are doing is grouping by each book and then selecting the ones that have more than 0 keywords and less than 10.

How do I use my join tables MySQL?

I have 3 tables in a MySQL database,
Author
Book
Author_has_Book.
The author has two columns
idauthor
name
Book also has two columns
idbook
name
Author_has_Book also has two columns
foreign keys of an author and a book book_idbook
author_idauthor.
I have successfully inserted an author and a book into both tables and I have entered their keys into the join table.
Now how do I use this join table to get all books by a certain author, or all authors for a book? Is this accomplished with joins?
edit: The suggested duplicate is not the same question.
It will get you all records
SELECT Author.*
FROM Author Author
INNER JOIN Author_has_Book AuthorHasBook
ON Author.idauthor = AuthorHasBook.author_idauthor
INNER JOIN Book Book
ON AuthorHasBook.book_idbook = Book.idbook
and if you wish to select any specific author, you just need to mention it in where clause, see example below:
SELECT Author.*
FROM Author Author
INNER JOIN Author_has_Book AuthorHasBook
ON Author.idauthor = AuthorHasBook.author_idauthor
INNER JOIN Book Book
ON AuthorHasBook.book_idbook = Book.idbook
WHERE Author.idauthor = 'your author id'
Try this query
select a.name,c.name from book a
join Author_has_Book b on a.idbook=b.idbook
join author c on b.idauthor=c.idauthor

MySQL relational view - join?

I'm relatively new to MySQL and I'm having no end of difficulty trying to work out how to do this. I've researched joining and such but I'm not really sure how to apply this.
I have three tables:
Artists Table
ID,
Name,
Description
Albums Table
ID,
Title,
Year,
Artist_ID
Tracks Table
ID,
Title,
Album_ID
Tracks are assigned to albums and albums are assigned to artists. (I did this through the relation view in phpmyadmin, engine is InnoDB).
What I'm trying to do is query ALL of the tracks for a particular artist (from their ID).
Is anyone able to point me in the right direction? Thanks in advance!
Using the implicit join syntax:
SELECT * FROM Tracks, Artists, Albums
WHERE Tracks.Album_ID=Albums.ID AND Albums.Artist_ID=Artists.ID
AND Artists.Name='foo'
Explicitly:
SELECT * FROM Artists
LEFT JOIN Albums ON Artists.ID=Albums.Artist_ID
LEFT JOIN Tracks ON Tracks.Album_ID=Albums.ID
WHERE Name='foo'
Or, with nested subqueries:
SELECT * FROM Tracks WHERE Album_ID IN
(SELECT ID FROM Albums WHERE Artist_ID IN
(SELECT ID FROM Artists WHERE Name='foo'))`
All three of these are identical (in the absence of NULL values). I recommend using the second one, as it is what seems to be selected by most SQL experts.
Use:
SELECT t.title
FROM TRACKS t
JOIN ALBUMS al ON al.id = t.album_id
JOIN ARTISTS a ON a.id = al.artistid
WHERE a.name = ?
If you already have the artists.id value:
SELECT t.title
FROM TRACKS t
JOIN ALBUMS al ON al.id = t.album_id
WHERE al.artist_id = ?
You may want to try the following:
SELECT tracks.title
FROM tracks
INNER JOIN albums ON (albums.id = tracks.album_id)
INNER JOIN artists ON (artists.id = albums.artist_id)
WHERE artists.name = 'A particular arist name';
Note that JOIN is a synonym for an INNER JOIN. We're basically using simple join syntax, using the inner join operation, which is probably the most common join type. I hope this gets you going in the right direction.
SELECT track.*
FROM artists, albums, tracks
WHERE artist.ID = 123
AND artist.id = albums.artist_ID
AND albums.id = tracks.Album_ID