I am trying to write a query to get a report that shows which book has been loaned out the most. I have a query to get the actual book loaned out most, but I need to be able to show the title of that book, which is in another table.
SELECT * FROM LOAN;
LOANID BOOKID CUSTID OUTDATE INDATE DUEDATE
SELECT * FROM BOOK;
AUTHORID BOOKID BKISBN BKSTATUS BKTITLE BKSERIES BKTYPE BKNUMBER
The following query is what I have so far and is getting the bookid.:
SELECT Q1.* FROM
(SELECT BOOKID, COUNT(*)
AS BOOK_COUNT
FROM LOAN
GROUP BY LOAN.BOOKID) Q1,
(SELECT MAX(Q2.BOOK_COUNT)
AS HIGH_COUNT
FROM (SELECT BOOKID, COUNT(*)
AS BOOK_COUNT
FROM LOAN
GROUP BY LOAN.BOOKID) Q2) Q3
WHERE Q1.BOOK_COUNT = Q3.HIGH_COUNT;
RESULT:
BOOKID BOOK_COUNT
---------- ----------
387 3
Now I need BkTitle from the Book Table.
Can anyone assist?
Try
select b.bookid, b.BKTITLE , count(l.loanid) as cnt_loan
from book b
inner join loan l on l.bookid = b.bookid
WHERE ROWNUM < 2
group by b.bookid
order by cnt_loan desc
Related
I am trying to select the highest pair from a table that has been created by joining (combining) two tables. I guess I should use a nested query but I'm not sure how.
I also came around a similar question that seems a bit less complex, but I am struggling to implement it into my problem.
Similar question: How to select max timestamp from each currency pair SQL?
My tables:
Book:
title
publisher
price
sold
book1
A
5
300
book2
B
15
150
book3
A
8
350
Publisher:
code
name
A
ABook
B
BBook
C
CBook
My query:
SELECT b.titel, p.name, max(b.price*b.sold) as 'Revenue"
FROM publisher p, book b
WHERE p.code = b.publisher
Gives:
title
publisher
Revenue
book1
ABook
1500
book2
BBook
2250
book3
ABook
2800
Desired output:
title
publisher
book2
BBook
book3
ABook
How to alter my query to get the highest revenue per book title and the corresponding publisher?
You can use this query:
SELECT b.titel, p.name
FROM publisher p, book b
WHERE p.code = b.publisher
order by b.price*b.sold desc
OR
select abc.titel,abc.name FROM (
select b.titel, p.name, max( b.price*b.sold) as balance
FROM publisher p, book b
WHERE p.code = b.publisher
group by b.titel, p.name ) abc order by abc.balance desc
You can use row_number window function to select the appropriate row for each group.
Your desired results don't align with your description (do you want a revenue column or not?), however this produces your desired output. Note the use of modern (for 30 years) ansi join syntax:
with sold as (
select *, Row_Number() over(partition by publisher order by (price * sold) desc) rn
from book b join publisher p on p.code=b.publisher
)
select title, name Publusher
from sold
where rn=1
I solved it by using a nested query and max function
select b.title, p.name
from book b join publisher p on p.code = b.publisher
where b.sold*b.price = (select max(sold*price)
from book t2
where t2.publisher = b.publisher
)
I have a table of books, a table of authors, and a "linker" table (many to many links between authors/books).
How do I find the authors with the highest number of books?
This is my schema:
books : rowid, name
authors : rowid, name
book_authors : rowid, book_id, author_id
This is what I came up with: (but it doesn't work)
SELECT count(*) IN book_authors
WHERE (SELECT count(*) IN book_authors
WHERE author_id = author_id)
And ideally I would like a report of the top 100 authors, something like:
author_name book_count
-----------------------------------
Johnny 25
Kelly 12
Ramboz 10
Do I need some kind of join? What is the fastest approach?
I'd join the three tables (via the book_authors table), group by the author, count occurrences and limit it to the top 100 rows:
SELECT a.name, COUNT(*)
FROM authors a
JOIN books_authors ba ON a.rowid = ba.author_id
JOIN books b ON ba.book_id = b.rowid
GROUP BY a.name
ORDER BY 2 DESC
LIMIT 100
EDIT:
Actually, we aren't using any data from books, just the fact the book actually exists, which can be inferred from books_authors, so this query can be improved by dropping the second join:
SELECT a.name, COUNT(*)
FROM authors a
JOIN books_authors ba ON a.rowid = ba.author_id
GROUP BY a.name
ORDER BY 2 DESC
LIMIT 100
Couldn't you just
select count(1) , Author_ID from Book_Authors group by Author_ID order by count(1) desc limit 100
The authors with the most books would be at the top (or the author_ID would be at least)
As for limiting to top 100... then add limit clause Sqlite LIMIT / OFFSET query
SELECT TOP 3 authors.author_name, authors.book_name, books.sold_copies,
(SELECT SUM(books.sold_copies) FROM books WHERE authors.book_name = books.book_name ) AS Total
FROM authors
INNER JOIN books
ON authors.book_name = books.book_name
ORDER BY sold_copies desc
I need one very expert help, I can't seem to find the answer to this, the problem is, find the titles and ISBNs of books that have the same title and publishers as at least 2 other books.
Order it by title.
So basically, everything is coming from the book table.
CREATE TABLE BOOK
(
ISBN VARCHAR2(20),
Title VARCHAR2(250) NOT NULL,
YearPublished NUMBER(4) NOT NULL,
PublisherName VARCHAR2(40) NOT NULL,
CONSTRAINT pk_isbnP PRIMARY KEY(ISBN)
);
Here is my rough draft:
select _____
from book b2
where ______ (select____ from book b2
where _____ = ______ and ______ =______)
Step 1: Find combinations of title and publisher that have at least 2 books:
SELECT title, PublisherName
FROM BOOK
GROUP BY title, PublisherName
HAVING COUNT(*) > 1
Step 2: find all other books that have this title and publisher:
SELECT *
FROM Books b1
WHERE EXISTS(
SELECT title, PublisherName
FROM BOOK b2
WHERE b1.title = b2.title AND b1.PublisherName = b2.PublisherName
GROUP BY title, PublisherName
HAVING COUNT(*) > 1
)
This ought to do it:
select isbn, title
from books
where (title,publishername) in(select title,publishername
from books
group by title,publishername
having count(*) >=3)
order by title;
select b1.title, b1.isbn
from book b1
inner join
(select title, publishername
from book
group by title, publishername having count(*) > 2) b2
on b1.title = b2.title and b1.publishername = b2.publishername
order by b1.title
The inner query fetches the titles/publishers of books where there are three or more duplicates. The outer query uses those results to get the associated ISBNs.
You can use group by statement here.
SELECT title
,isbn
FROM BOOKS
group by title, isbn
having COUNT(1) >= 2 order by title;
List the bookid and bookname of the books which has max cost per copy
Manuscript table
Bookid Authorid Bookname Genre numberofcopies Amount
here is what i tried.
select bookid, bookname
from manuscript
where bookid=MAX(costpercopy.bookid)
select bookid,MAX(amount/Numberofcopies) AS costpercopy
from manuscript
group by bookid;
The costpercopy column doesn't exist and needs to be created by dividing amount by numberofcopies.
I need some help as where to put the subquery.
Below query should help you:
SELECT BOOKID, BOOKNAME, (AMOUNT/NUMBEROFCOPIES) costpercopy FROM
manuscript,
(
SELECT MAX(AMOUNT/NUMBEROFCOPIES) REQVALUE FROM manuscript
) SUBTAB
WHERE (AMOUNT/NUMBEROFCOPIES) = REQVALUE;
Same query, using join would be like:
SELECT BOOKID, BOOKNAME, (AMOUNT/NUMBEROFCOPIES) costpercopy FROM manuscript INNER JOIN
(
SELECT MAX(AMOUNT/NUMBEROFCOPIES) REQVALUE FROM TESTDATA
) SUBTAB
ON (AMOUNT/NUMBEROFCOPIES) = REQVALUE
This query orders all books by the costpercopy putting the most costly first:
select bookid, bookname
from manuscript
order by amount/numberofcopies desc;
Depending of your type of database you can add "fetch first 1 only" or "limit 1" to get only the first result.
I am trying to create a query that will list all books by the same author. Most of the list has only one book by one author, but I want the author that has multiple books listed in db to display those book for that author.
I have two tables:
Book - AuthorID, BkTitle, etc
Author - AuthorID, AuthFName, AuthLName
I want the result to be sorted by AuthLName and the report to consist of any books in db that have same authorid.
Example result wanted:
AUTHORID BKTITLE AUTHFNAME AUTHLNAME
--------- ----------------- ------------ -----------
504 KNIGHT FREEDOM Chris Feehan
504 KNIGHT SHOWDOWN Chris Feehan
Currently, I have the following code:
select AUTHORID, BKTITLE
from BOOK
where AUTHORID in
(select AUTHORID from
(select AUTHORID,
count(*) as BOOK_COUNT
from BOOK
group by AUTHORid
order by AUTHORid )
where BOOK_COUNT >= 2);
which gives:
AUTHORID BKTITLE
---------- --------------------
504 KNIGHT FREEDOM
504 KNIGHT SHOWDOWN
I need to find a way to get the information from the Author Table and add it in this.
This should do:
SELECT b.AUTHORID, b.BKTITLE, a.AUTHFNAME, a.AUTHLNAME
FROM BOOK b
INNER JOIN AUTHOR a
ON b.AUTHORID = a.AUTHORID
AND b.AUTHORID IN
(
SELECT AUTHORID
FROM BOOK
GROUP BY AUTHORID
HAVING COUNT(AUTHORID) > 1
)
ORDER BY a.AUTHLNAME, a.AUTHFNAME
How about this - updated to use a CTE (Common Table Expression) first to figure out which authors have more than one book in the database table BOOK, and then listing only those authors and their books:
;WITH AuthorsWithMoreThanOneBook AS
(
SELECT AUTHORID, BOOK_COUNT = COUNT(*)
FROM BOOK
GROUP BY AUTHORID
HAVING BOOK_COUNT > 1)
)
SELECT
b.AUTHORID, b.BKTITLE, a.AuthFName, a.AuthLName
FROM
BOOK b
INNER JOIN
AUTHOR a ON b.AuthorID = a.AuthorID
INNER JOIN
AuthorsWithMoreThanOneBook A2 ON a.AuthorID = A2.AuthorID
ORDER BY
a.AuthLName, a.AuthFName
Update: OK, you're using Oracle .... not sure (haven't used it in ages) - but can't you just extend your original query something like this:
select bk.AUTHORID, bk.BKTITLE, a.AUTHORFNAME, a.AUTHORLNAME
from BOOK AS bk
INNER JOIN AUTHOR AS a ON a.AUTHORID = bk.AUTHORID
where bk.AUTHORID in
(select AUTHORID from
(select AUTHORID,
count(*) as BOOK_COUNT
from BOOK
group by AUTHORid
order by AUTHORid )
where BOOK_COUNT >= 2);
Not sure if/how Oracle supports those table aliases (BOOK AS bk) - but I'm pretty sure it does support it some way or another....
You can do this with only one access to each table:
SELECT * FROM
(
SELECT AuthorID, BkTitle, AuthFName, AuthLName
,COUNT(*) OVER (PARTITION BY AuthorID)
AS c
FROM BOOK
JOIN AUTHOR USING (AuthorID)
)
WHERE c > 1;