I have a table Books which has its bookauthorID in another table that is Author
BOOK
ID BOOK NAME AUTHORID
0 A NULL
1 B NULL
2 C NULL
AUTHOR
BOOKID AUTHORID
0 123
1 1234
2 12345
Now I have to fill up AuthorID column in Book table from Author table where BOOK.ID = AUTHOR.BOOKID as the BOOK.AUTHORID column was added later in the table
So far
I have this
WITH ALLBOOKSANDAUTHORIDS AS
(
SELECT * FROM BOOK INNER JOIN AUTHOR on BOOK.ID = AUTHOR.BOOKID
)
I now have a table telling each book and its author ID
but how can I update the BOOK.AUTHORID with correct values, getting values from Author table and putting them in book ?
It is like a for loop where go to each row in Book table and check which ID matches in the Author table, then get the AUTHORID and update it in book table.
Please tell how to write the SQL ?
Thanks
Aiden
You can do this with an update/join:
update b
set b.authorid = a.authorid
from book b join
author a
on b.id = a.bookid
where b.authorid is null;
Simply join those table and do update.
update book b join author a on (a.bookid=b.id)
set b.AUTHORID=a.AUTHORID
UPDATE BOOK
SET AUTHORID = AUTHOR.AUTHORID
FROM BOOK INNER JOIN AUTHOR ON BOOK.ID = AUTHOR.BOOKID
First of all ID can not be Zero, And ans to your question is may be simaple Update statement with join
Update B
SET B.AUTHORID=A.AUTHORID
FROM Book B
INNER JOIN AUTHOR A ON A.BOOKID = B.ID
We can also do this I think
Update b
Set b.AUTHORID = ( Select top 1 a.AUTHORID From AUTHOR a
where b.ID = a.BOOKID)
Related
I have three tables in a SQLite database: book, author and loaned_books. They look like this
book: _id | author_id | title | subject
author: _id | first_name | last_name
loaned_books: _id | book_id | loan_date | due_date
The author_id is a foreign key for the author table, and the book_id is a foreign key for the book table.
I am trying to create a query that extracts all the books (with their associated author) which are not loaned. So far, I have this query:
SELECT book.title, book.subject, author.first_name, author.last_name
FROM book, author
INNER JOIN loaned_books ON book._id != loaned_books.book_id AND book.author_id = author._id
This one does the job with the exception that all the records returned are duplicated. I have tried using DISTINCT on the column names, but the result is wrong as well.
What would be a query that returns all the books (with their associated author) that are not loaned?
The way you join book and author:
FROM book, author
is wrong because it returns the cartesian product of the 2 tables.
You need a LEFT JOIN to loaned_books and return the non matching rows (meaning the books that don't exists in loaned_books)
SELECT b.title, b.subject, a.first_name, a.last_name
FROM book AS b
INNER JOIN author AS a ON b.author_id = a._id
LEFT JOIN loaned_books AS l ON b._id = l.book_id
WHERE l._id IS NULL
Could you please try executing this:
SELECT distinct book.title, book.subject, author.first_name, author.last_name
FROM book inner join author on book.id = author._id left outer join loaned_books ON book._id = loaned_books.book_id where loaned_books.book_id is null or length(loan_date) = 0 or loan_date = ''
I am trying to list all book titles given that they have the same authors who wrote the book 'Database principles'. I am not sure on how to link the author who wrote the book to the book title from the table Book and Author. How do i do this?
Assuming that BOOK table has a column AID that is an FK pointing to AUTHORID of the AUTHOR table.
There are many ways of doing so.
Inner Query
SELECT B.* FROM BOOK B WHERE B.AID IN (SELECT AID FROM BOOK WHERE TITLE LIKE '%?%');
Joines
SELECT B1.* FROM BOOK B1 , BOOK B2 WHERE B1.AID = B2.AID AND B2.TITLE LIKE '%?%';
Left outer join
SELECT B1.* FROM BOOK B1 LEFT OUTER JOIN BOOK B2 ON B1.AID = B2.AID WHERE B2.TITLE LIKE '%?%';
I am using Postgresql in my company as a primary store and I'm struggling to implement an update query involving three different tables.
Here is the schema :
Table 1 has entity_id, entity_type and company_id (referencing Company.id) columns.
Company has id column
Special_company has id (which corresponds to Table1.entity_id) and company_id (referencing Company.id)
I would like to update all the rows of Table 1 where Table1.entity_type = 'SpecialCompany' in order to fill Table1.company_id such that :
Table1.entity_id = SpecialCompany.id and SpecialCompany.company_id = Company.id
I've started something like that:
UPDATE Table1
SET company_id = (select c.id
FROM company c
INNER JOIN special_company w ON c.id=w.company_id
WHERE w.id=709)
WHERE entity_type='SpecialCompany' AND entity_id=709;
But I am not able to replace 709 by all the Table1.entity_id where Table1.entity_type = 'SpecialCompany'.
Any help would be much appreciated.
I assume you are looking for something like this.
update t
set t.company_id=c.id
from
Company C
INNER JOIN special_company w ON c.id=w.company_id
INNER JOIN Table1 t on t.entity_id=w.entity_id
Where t.entity_type = 'SpecialCompany'
I'm answering to my question as I found the solution :
UPDATE Table1 t
SET company_id = c.id
FROM Company c
INNER JOIN special_company w ON c.id=w.company_id
WHERE
t.entity_type = 'SpecialCompany' AND t.entity_id=w.id;
Thanks #Krishna for your help !
I have Book and Author tables. Book have many Authors (I know that it should be many-to-many it's just for the sake of this example).
How do I select all books that have been written by authors: X and by Y in one sql query?
EDIT
Number of authors can be variable - 3, 5 or more authors.
I can't figure it out now (I've tried to do JOINs and sub-queries).
SELECT * FROM book ...?
Try this:
SELECT
B.Name
FROM Books B
JOIN Authors A
ON B.AuthorID = A.ID
WHERE A.Name IN ('X', 'Y')
GROUP BY B.Name
HAVING COUNT(DISTINCT A.ID) = 2
You can just double join the authors table.
SELECT Book.* from Book
JOIN Author author1
ON author1.book_id = Book.id AND author1.author_name = 'Some Name'
JOIN Author author2
ON author2.book_id = Book.id AND author1.author_name = 'Some Other Name'
GROUP BY Book.id
The JOINs ensure that only books with Both authors are returned, and the GROUP BY just makes the result set only contain unique entries.
It's worth noting by the way that this query will bring back books that have at least the two authors specified. For example, if you want books only by Smith and Jones, and not by Smith, Jones and Martin, this query will not do that. This query will pull back books that have at least Smith and Jones.
select * from book where author=.... ?
I found it hard to understand your structure but this seems like the best way?
Hope this helps
I am assuming that your Author table has a Book ID (as this would give many author to one book).
SELECT * from Books Where ID IN
(SELECT BookID from Author A
JOIN Author B on A.BookID = B.BookID and A.ID <> B.ID
WHERE A.ID IN ('X', 'Y') AND B.ID IN ('X','Y'))
EDIT: Hamlet's answer is much better (scaleable).
I have 2 tables: authors and books.
in authors i have attributes authorID, authorName, and authorDOB.
authorID is the primary key in this table.
in the books table i have attributes bookISBN, authorID, etc.
with bookISBN as the primary and authorID as the foreign key
i am trying to perform a query where given an author name, perform a
count of all the books by that author.
here is what i got:
SET #ID =
AuthorID
FROM authors
WHERE ('Mark Twain' = AuthorName);
SELECT COUNT(*)
FROM books
WHERE (AuthorID = ID);
Any help would be greatly appreciated
Try:
SELECT a.authorId, a.authorName, count(*)
FROM authors a
INNER JOIN books b ON b.AuthorID=a.AuthorID
WHERE ('Mark Twain' = a.AuthorName)
GROUP BY a.authorId, a.authorName
i am trying to perform a query where given an author name, perform a count of all the books by that author.
Try
select count(1)
from books b
inner join authors a on a.AuthorID=b.AuthorID
where a.AuthorName='Mark Twain'
You can use a function as well if you think you'd be doing the search more frequently. Just an idea.
go
create function totalbooksbyauthor (#authorname varchar(20) ) returns table
as return
select a.authorid, a.authorname, COUNT(b.bookname) bookcount
from authors a
inner join books b
on a.authorID = b.authorID
where a.authorname = #authorname
group by a.authorid, a.authorname
go
select * from totalbooksbyauthor ('Mark Twain')