Mysql Joining data from 3 tables - mysql

I can't seem to figure out what join I need to do. I have 3 tables which have all the information. I've map out the steps but I'm unsure what to do now, I need to display all the books listed from a specific author.
There is 3 tables I need to use
Author - which contains author_code, fname & lname.
Book - which contains book_code, title, publisher_code, type, price and paperback
Wrote - which contains book_code, author_number and sequence
Here's the code so far, really I know I should use author name but i can't figure it out.
SELECT BOOK_CODE
FROM WROTE
WHERE AUTHOR_NUM = 20
LEFT JOIN AUTHOR
ON WROTE.AUTHOR_NUM = AUTHOR.AUTHOR_NUM;

You need list of book, so start with book table then join it with wrote to get specific author and then join to author to get author data
SELECT BOOK_CODE
FROM BOOK
INNER JOIN WROTE
ON WROTE.BOOK_CODE = BOOK.BOOK_CODE
AND WROTE.AUTHOR_NUM = 20
INNER JOIN AUTHOR
ON AUTHOR.AUTHOR_NUM = WROTE.AUTHOR_NUM

SELECT Book.book_code
FROM Book
LEFT JOIN WROTE ON WROTE.book_code = Book.book_code
LEFT JOIN AUTHOR ON AUTHOR.author_code = WROTE.author_number
WHERE AUTHOR.author_code IN (123,456)

Related

MySQL how to join 3 tables when one doesn't have a common key

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

Looking for help on joining query

im taking my very first programming (sql) class. I've got no tech background whatsoever and I'm having a little trouble getting the code down.
here is the what the database looks like.
BOOK
BOOK_CODE (UNIQUE)
BOOKTITLE
PUBLISHER_CODE
BOOKTYPE
PRICE
INVENTORY
BOOK_CODE (UNIQUE)
BRANCH_NUM (UNIQUE)
ON_HAND
The question is, list the books (titles) that are available in branches 3 and 4 (on both at the same time).
Im thinking i need to use the following tables: booktitle on the book table , bookcode on both tables ( book and inventory), and branch_num on inventory table.
also the answer can only show the book titles available on branches 3 and 4 (at the same time) and no other columns.
sorry if im making no sense. like i said im a n00b.
select distinct BOOKTITLE from BOOK a, INVENTORY b
where a.BOOK_CODE = b.BOOK_CODE and a.BOOK_CODE in
(select distinct p.BOOK_CODE from Inventory p, Inventory q where p.BOOK_CODE =
q.BOOK_CODE
and p.BRANCH_NUM = 3 AND q.BRANCH_NUM = 4);
SELECT BOOKTITLE FROM BOOK
WHERE BOOK_CODE IN (SELECT BOOK_CODE FROM INVENTORY WHERE BRANCH_NUM = 3 AND ON_HAND > 0)
AND BOOK_CODE IN (SELECT BOOK_CODE FROM INVENTORY WHERE BRANCH_NUM = 4 AND ON_HAND > 0);
OR
SELECT BOOKTITLE FROM
(
SELECT BOOK.BOOK_CODE, BOOKTITLE, COUNT(*) AS BRANCH_COUNT FROM BOOK
INNER JOIN INVENTORY ON BOOK.BOOK_CODE = INVENTORY.BOOK_CODE
AND INVENTORY.BRANCH_NUM IN (3, 4)
GROUP BY BOOK.BOOK_CODE, BOOKTITLE
) B
WHERE B.BRANCH_COUNT = 2;
Please try this:
SELECT BK.BOOKTITLE
FROM BOOK BK
INNER JOIN INVENTORY INV1
ON INV1.BOOK_CODE = BK.BOOK_CODE
INNER JOIN INVENTORY INV2
ON INV2.BOOK_CODE = BK.BOOK_CODE
WHERE INV1.BRANCH_NUM = 3
AND INV2.BRANCH_NUM = 4
Your question tells you the fields you need from the table, which gives you this as a starting point:
SELECT booktitle FROM book . . .
That alone will give you a list of every booktitle in the table book, but you want to filter it down to only those books in both branch_num 3 and 4.
When you JOIN two or more tables, you're looking to match rows based on some shared valued; book_code, in this case.
Since you want to see only those books in both tables, you'll want to use an INNER JOIN. (I'm assuming ON_HAND is an INT describing the number of copies in the branch.)
SELECT booktitle FROM book
INNER JOIN inventory USING (book_code)
WHERE inventory.onhand > 0
That query will return a list of every book that is available in any branch. Modifying the query, you can restrict it only to those books in branch_num 3:
SELECT booktitle FROM book
INNER JOIN inventory USING (book_code)
WHERE inventory.onhand > 0 AND inventory.branch_num = 3
...but you need books in both branches 3 and 4, so you'll need to do another join on the inventory table. But how can you distinguish the two? Use table aliases:
SELECT booktitle FROM book
INNER JOIN inventory AS inventory1 USING (book_code)
INNER JOIN inventory AS inventory2 USING (book_code)
WHERE inventory1.onhand > 0 AND inventory1.branch_num = 3 AND inventory2.onhand > 0 AND inventory2.branch_num = 4
That should give you what you're looking for.
For a much better explanation of joins, see MySQL Joins and A Visual Explanation of SQL Joins.
[Note: this problem could also be using subqueries, which you should try to do.]

Joins for queries

I am preparing for my exams this week and I saw a past paper question like this:
Lecturer
lec_id
lec_name
phone
dept
requests
lec_id
book_id
qty
date
book
book_id
title
author
cost
supplier
I need to write a MySQL command that will find the name and phone number of each lecturer requesting the book with id# 123.
I tried creating the query as shown below:
SELECT lec_name, phone FROm lecturer
LEFT JOIN requests ON requests.lec_id = lecturer.lec_id
LEFT JOIN requests ON requests.book_id = book.book_id
WHERE book.book_id = 123
However I keep getting the error Not unique table/alias: 'requests'
Best to start from the book so the WHERE clause is cleaner, and perhaps more intuitively adapted to searching for another specific book and/or all books:
select book.book_id, book.title, lecturer.lec_name, lecturer.phone
from book
left join requests on book.book_id = requests.book_id
left join Lecturer on requests.lec_id = Lecturer.lec_id
where book.book_id = 123
SELECT lec_name, phone FROm lecturer
LEFT JOIN requests ON requests.lec_id = lecturer.lec_id
AND requests.book_id = book.book_id
WHERE book.book_id = 123

Fetching data from many-to-many relationships

I want to fetch the title from book table and the subject name from subject table for all the books of a certain author
Here is the tables relationships
I have tried to select the title and the subject from the tables but I can't get it to work with the many to many relationship
SELECT book_title,subject_name FROM book,subject WHERE $subject_ID = subject_ID INNER JOIN book_author ON author_ID = '$author_ID'
I thought about making two separate queries, if someone could help me on that I would be really glad.
Try this one:
SELECT book_title, subject_name
FROM Book
INNER JOIN Book_Author ON Book.book_ISBN = Book_Author.book_ISBN
INNER JOIN Author ON Book_Author.author_ID = Author.author_ID
INNER JOIN Subject ON Subject.subject_ID = Book.subject_ID
WHERE author_lastname = [whatever];
And nice job posting the model :)
Edit to match the exact need:
SELECT book_title, subject_name
FROM Book
INNER JOIN Book_Author ON Book.book_ISBN = Book_Author.book_ISBN
INNER JOIN Subject ON Subject.subject_ID = Book.subject_ID
WHERE author_ID = '11';
And by the way, you're having an "Column 'author_ID' in where clause is ambiguous" because this column appears both in Book_Author and Author. That's why you have to prefix it with the table name :)

How do I link tables with id from a list stored as XML in a column

Hopefully the question explains it well. I have a DB for a Library. Since they can be used many times, and contains more data than just a name, I have a table for Authors. Then there's a table for Books. I have no problem linking Authors to Books via a column called Author_id.
What I'm trying to do is have a column called Author_IDs that contains a list of id's, since a book can have multiple IDs. In the Author_IDs column I have:
<id>3478</id>
<id>6456</id>
Using the ExtractValue function in MySQL I can link the table with one or the other id using:
WHERE Author.id = ExtractValue(Book.Author_IDs,"/id[2]") // to get the second ID.
My question is, I want to be able to automatically display all of the authors of a book, but don't know how to link to it more than once, without looping. How can I get the results to show me all of the authors?
(Or is there a better way to accomplish this?)
Firstly, I have to vote against your storage method. Storing data as xml inside a mysql column should be avoided if possible. If you use a normal approach you will find this problem to be much easier.
Create a table:
book_authors
book_id author_id
------- ---------
1 1
1 2
1 3
2 2
2 4
Then to get all of the authors associated with a certain book it's a simple query.
Select
b.book_id,
b.book_name,
GROUP_CONCAT(a.author_name) AS 'authors'
FROM
book_authors ba LEFT JOIN
books b ON ba.book_id = b.book_id LEFT JOIN
authors a ON ba.author_id = a.author_id
GROUP BY
ba.book_id
Not sure I understand completely. Could something like this do the trick?
select a.* from tblBooks b
left join tblAuthors a on (b.authors = concat('%', a.id, '%')
where b = 'book id';
I would have done it like this
Structure
tblBooks
--------
book_id
book_name
tblAuthors
----------
author_id
author_name
tblBooksToAuthors
-----------------
id
book_id
author_id
Query
select a.*
from tblAuthors a
left join tblBooksToAuthors b2a on (b2a.author_id = a.author_id)
where b2a.book_id = {your book id};