I have the following four tables:
Subscription:
book_id, duration, subscriber
Book:
book_id, book_name
Genre:
genre_id, genre_name
book_to_genre:
genre_id, book_id
For a certain user (subscriber) I would like to get all rows from subscription. The book name should be fetched from table Book. I know this is done with an inner join:
SELECT Book.book_name, Subscription.duration from Subscription INNER JOIN Book on Subscription.book_id = Book.book_id where Subscription.subscriber = "somevalue";
What if I would like to fetch genre_name from table Genre, where Genre.genre_id = book_to_genre.genre_id for that book?
Here is a modified version of your initial query that will return genre_name:
- I added the field genre_name in the SELECT part
- I added table aliases to make it easier to read
- I added 2 INNER JOIN: one between tables book and book_to_genre, the other between tables book_to_genre and Genre
SELECT b.book_name, s.duration, g.genre_name
FROM Subscription s
INNER JOIN Book b on s.book_id = b.book_id
INNER JOIN book_to_genre bg ON b.book_id = bg.book_id
INNER JOIN Genre g ON bg.genre_id = g.genre_id
where s.subscriber = "somevalue";
Documentation:
- SELECT
- JOIN
Related
I have 3 tables, 'film', 'actor' and 'cast'. I want to get a list of actors that are in a certain film, but I am brand new to SQL and cannot figure out how to join the tables.
I am comfortable with the SELECT and WHERE, just not the FROM.
Film has the following fields: id, title and year.
Actor has the fields id and name.
Cast has the fields filmid and actorid
You need to join the tables like this
select a.name
from actor a
join cast c on a.id = c.actorid
join film f on f.id = c.filmid
where f.title = 'your movie title'
I have three tables and I need to join as follows.
INVENTORY
BOOK_CODE, BRANCH_NUM, ON_HAND
BOOK
BOOK_CODE, TITLE
AUTHOR
AUTHOR_NUM, AUTHOR_LAST
Basically, I need to select the author name, book title, and on-hand count for all books from Branch 4 (in inventory). The problem is, the AUTHOR table has to be reached through a fourth table.
WROTE
BOOK_CODE, AUTHOR_NUM
If all the tables had that BOOK_CODE, I could do it easy, but I can't figure out how to jam it all into one query. I've tried the following:
SELECT TITLE, AUTHOR_LAST, ON_HAND
FROM BOOK, AUTHOR, INVENTORY
WHERE BOOK.BOOK_CODE = INVENTORY.BOOK_CODE
AND AUTHOR_NUM IN
(SELECT AUTHOR_NUM
FROM WROTE
WHERE WROTE.BOOK_CODE = INVENTORY.BOOK_CODE)
AND BRANCH_NUM='4';
But this returns the wrong fields, so I don't know what I'm doing wrong.
You can "chain" your joins:
SELECT title, author_last, on_hand
FROM book b
JOIN inventory i ON b.book_code = i.book_code
JOIN wrote w ON b.book_code = w.book_code
JOIN author a ON a.author_num = w.author_num
WHERE branch_num = 4
You should try Joining it will be Helpful rather that Sub query
SELECT a.AUTHOR_LAST,d.TITLE,c.ON_HAND FROM WROTE a INNER JOIN AUTHOR b
ON a.AUTHOR_NUM=b.AUTHOR_NUM INNER JOIN INVENTORY c
ON c.BOOK_CODE=a.BOOK_CODE INNER JOIN BOOK d
ON a.BOOK_CODE=d.BOOK_CODE
WHERE c.BRANCH_NUM=4
Try like this
I need to write a query for a scout database that compares the requirements of a badge with the skills a given member has already earned. The purpose being that several skills are applicable to multiple badges. My relevant tables (there are many) look like this:
Badge_Table:
Badge_ID,
Badge_Name,
Badge_Description,
Badge_Skills_Table:
Badge_Skill_ID,
Badge_ID,
Skill_ID,
Skills_Table:
Skill_ID,
Skill_Name,
Skill_Description,
Skills_Earned_Table:
Skills_Earned_ID
Skill_ID
User_ID
User_Table:
User_ID,
Name,
Age,
Address
Primary keys are shown in italics, and the foreign key relationships go from Badge_table to Badge_Skills_Table to Skills_Table to Skills_Earned_table to User_Table.
So far I have came up with the following ideas:
Selects all badges for named skill
SELECT badge_table.badge_name
FROM (badge_table
INNER JOIN badge_skills_table ON badge_ID
INNER JOIN Skills_Table ON skill_Id)
WHERE Skills_Table.Skill_Id = 1;
Selects all badges for each skill
SELECT badge_table.badge_name
FROM (badge_table
INNER JOIN badge_skills_table ON badge_ID
INNER JOIN Skills_Table ON skill_Id)
WHERE Skills_Table.Skill_Id = Skill_Badge_Table.Skill_Id
Selects all badges for named skill for named User - not quite working
SELECT badge_table.badge_name
FROM (badge_table
INNER JOIN badge_skills_table ON badge_ID
INNER JOIN Skills_Table ON skill_Id
INNER JOIN Skills_Earned_Table On skill_ID
INNER JOIN users_table ON user_ID)
WHERE Skills_Earned_Table.User_ID= 1 AND Skills_Earned_Table.SKILL_ID = Skill_Badge_Table.skill_ID
So can anyone help guide me with the following:
How to return all badges that a given skill is applicable for. (Done)
How to return all badges that a given scout has earned skills towards.
To return all badges the a given scout has earned all the skills for.
I'd appreciate any help you can offer,
You have no <conditions> in your ON clause. Try my query below:
SELECT A.badge_name
FROM badge_table A
INNER JOIN badge_skills_table B ON A.badge_ID=B.badge_ID
INNER JOIN Skills_Table C ON B.skill_Id=C.skill_ID
INNER JOIN Skills_Earned_Table D ON C.skill_ID=D.skill_ID
INNER JOIN users_table E ON user_ID ON D.user_ID=E.user_ID
WHERE D.User_ID= 1 AND D.skill_ID = B.skill_ID
Books
bookid (PK)
title
price
author
authored (PK)
authorname
publisher
pubid (PK)
pubname
bookauthors
bookid (FK)
authorid
bookpublisher
bookid (FK)
pubid
I want to join all five tables and get these column values:
bookid
title
price
authorname
pubname
I should get only one row for a query to get above result. What I wrote was:
select books.*, authors.authorname
from authors,books
inner join bookauthors on books.bookid = bookauthors.bookid
inner join publisherbook on books.bookid = publisherbook.bookid
where books.bookid = 459567;
but instead I am getting many rows with duplicate data.
You need to use joins for all the tables. Using multiple tables in the FROM clause results in a Cartesian product. Try this
SELECT books.bookid, books.title, books.price, authors.authorname
FROM books
INNER JOIN bookauthors ON books.bookid = bookauthors.bookid
INNER JOIN publisherbook ON books.bookid = publisherbook.bookid
INNER JOIN authors ON bookauthors.authorid = authors.authorid -- assuming you meant authorid and not authored
WHERE books.bookid = 459567;
Of course, if your book has multiple authors, you will get multiple rows in your resultset.
I'm not sure why you're joining in publisherbook (or bookpublisher from your original list) unless you're just ensuring that your book has a publisher. Again, multiple publishers will result in even more (duplicate) results.
If you just want to make sure your book has at least one publisher, try this instead...
SELECT books.bookid, books.title, books.price, authors.authorname
FROM books
INNER JOIN bookauthors ON books.bookid = bookauthors.bookid
INNER JOIN authors ON bookauthors.authorid = authors.authorid -- assuming you meant authorid and not authored
WHERE EXISTS (
SELECT 1 FROM publisherbook
WHERE publisherbook.bookid = books.bookid
) AND books.bookid = 459567;
I am working with MySql 5.1 and am building my first many-to-many database. I understand the concepts, I have 3 tables:
Albums, with a unique ID
Genres, with a unique ID
album_genres with columns for each of the ID's from Albums and Genres.
The issue I am having is that, of course, 1 album can have multiple genres. But when I do a search, I'm really in the dark about how to structure it so during searches, I get all the genres for each individual album. Please note, this is not the loading of 1 album, but doing a search that will net 1 or more albums.
Sorry I don't really have anything to show what I've tried because I'm not even sure where to begin.
I'm sure it's easy enough. But all the tutorials I could find only address the basics of M2M but not how to get multiple matching entries.
After looking at many great suggestions, I have built this query:
SELECT
album.album_title,
Concat(genre.genre_id, ',') as GenreName,
count(album.album_id) as GenreCount
FROM $this->album_tbl album
JOIN wp_musicmgr_albgnr albgnr ON albgnr.albgnr_album_fk = album.album_id
JOIN $this->genre_tbl genre ON genre.genre_id = albgnr.albgnr_genre_fk
GROUP BY album.album_id
Which is producing this:
[0] => stdClass Object
(
[album_title] => album q
[GenreName] => 1,
[GenreCount] => 3
)
However, as you can see. Despite having a count of 3 hits on genres, it is listing the first one.
If I got the question you need output like
AlbumName | Genre1,Genre2.........
FOr this you need to use GroupBy
SELECT A.album_name as AlbumName, GROUP_CONCAT(G.genre_name) as GenreName, count(A.ID) as GenreCount
FROM Album A
JOIN album_genres AG
ON (A.ID = AG.album_ID)
JOIN Genre G
ON (G.ID = AG.genre_ID)
Group by A.ID
Join on the two tables.
SELECT cols FROM Albums
JOIN album_genres USING (albumID)
JOIN Genres USING (genreID)
WHERE albumName LIKE :search
Select * from Albums a, Genres g, album_genres ag
where a.unique_id = ag.a_unique_id and g.unique_id = ag.g_unique_id and a.name like '%album-name%'
album-name is the value of album in table album
Also in place of star(*) in Select *, please do put columns name's from Gener table.
To get all Genres of an Album the query would be
SELECT A.album_name, G.genre_name FROM Album A
JOIN album_genres R
ON (A.ID = R.album_ID)
JOIN Genre G
ON (G.ID = R.genre_ID)
WHERE A.ID = '5'
Where 5 would be the album unique id. The basic concept is that you should join the 3 tables, and use JOIN - ON to match the ids of each columns in the relationship table to the entity table one
EDIT: If you want a list of every album with every genre like this one:
Album - Genre
Al01 - Rock
Al02 - Rock
Al01 - Rock
Al01 - Metal
Al03 - Metal
just remove the WHERE A.ID = '5'.
Updated (New Answer):
Note: Tested.
select a.name, group_concat(g.name separator ', ')
from albums a
inner join album_genre ag on a.id = ag.albumid
inner join genres g on ag.genreid = g.id
group by a.id;
Note: GROUP_CONCAT has a maximum length limit. Default limit is 1024, but can changed by modifying group_concat_max_len. Read more: http://dev.mysql.com/doc/refman/5.7/en/group-by-functions.html#function_group-concat
Old answer:
Search for Albums:
SELECT a.album_name, a.AlbumId FROM `Albums` a
INNER JOIN `album_genres` ag on a.AlbumId = ag.AlbumId
INNER JOIN `Genres` g on ag.GenreId = g.GenreId
WHERE
a.album_name = 'Michael Learns To Dance' AND
g.genre_name = 'ROCK'
GROUP BY a.AlbumId;
Foreach row... perform another search query:
SELECT g.genre_name FROM `Genres` g
INNER JOIN `album_genres` ag on g.GenreId = ag.GenreId
WHERE ag.AlbumId = 1;
....[continue for next row]....
....
WHERE ag.AlbumId = 2;
WHERE ag.AlbumId = 3;
WHERE ag.AlbumId = 4;
......
WHERE ag.AlbumId = 1000;