Counting positions in a row oracle - sql

I'm making bookstore database and in the table "Authors" I've got column where i'd like to count books written by author in the table "Books". Table "Books" has foreign key "id_author". I have no idea how to do it, it's something like
SELECT COUNT(*) FROM Books WHERE id_author = "id of chosen author"
What to write in code in place of "id of chosen author"?
How to put it in a row in table "Author"?

You could join on the authors table and query by its columns (e.g., the first and last name):
SELECT COUNT(*)
FROM books b
JOIN author a ON b.id_author = a.id
WHERE a.firstname = 'John' AND a.lastname = 'Doe'

Depending on the application you have, the application might already have the author id. This means that you could just do a
SELECT COUNT(*) FROM Books WHERE id_author = "id of author provided by application"
Although the difference is probably not large compared to Mureinik's answer, this can enhance your performance on large databases as you do not have to do the join between author and book table.

Number of books by author:
select a.author, count(1)
from author a
join books b
on a.id = b.id_author
group by a.author

Related

Updating a table in oracle from another table with duplicate records present

I have two tables, lets say table books and table authors.
Table books has 4 fields, BookId, Title, Author, Publisher
Table authors has 5 field AuthorID, Title, Author, Publisher, Price
I want to update book to have the price field from authors. There is no one unique key so the criteria is if Title or Author or Publisher match then add that price to books. In my case authors has many duplicate values in Title, Author or Publisher so I get update errors because of duplicates. So basically how in oracle can I update books with that criteria and in case of duplicates just choose any record, it doesn't matter which and put it in there? Other languages have the top command that you can use to do such a thing but it looks like Oracle lack that.
I have tried various merge and update statements on my own with no luck. Something like:
UPDATE books n
set n.price = (
select t.price from authors t where
n.title= t.title or
n.author = t.author or
n.publisher = t.publisher)
But that statement isn't checking for duplicates and stopping them thus failing so I am missing that key.
The simple way is:
UPDATE books n
set n.price = (
select t.price from authors t where
( n.title= t.title or
n.author = t.author or
n.publisher = t.publisher )
and rownum = 1)

SQL: Querying Against Composite Entity

I'm trying to figure out how to query against a composite key.
In my select result, I want the book name, author, category, and selling price. So far I have select title,category,price from books1 where books1.category='MYS';
but I'm not sure how to go about getting the author name.
I'm not sure why you have books1 when the model show the table named books. Books is a horrible name for a table -- typically in relational databases you use the singular -- eg book.
Here is how you do a join:
Select a.First, a.Last
from books b
join books_authors ab on b.b_code = ab.book_code
join authors a on ab.authorId = a.id
where b.category = 'MYS'
also all of your field names have spaces in them -- I don't know what platform you are using so I've no idea how to escape the names. Using spaces in field name is non-standard and not acually SQL. I'd advise against it whenever possible.

SQL - Nested Sub-Queries

Using postgresql, I have to create a view called 'no_cat_customers' that returns the first name, last name of any customer who has not been shipped any edition of the book named 'The Cat in the Hat'. This should be done using universal quantification. The error I'm getting is - "ERROR: EXCEPT types integer and text cannot be matched" in reference to line 7 (EXCEPT (SELECT shipments.isbn).
CREATE VIEW no_cat_customers(customer_first_name, customer_last_name)
AS SELECT first_name, last_name
FROM customers
WHERE EXISTS (SELECT c_id
FROM shipments
WHERE customers.c_id = shipments.c_id
EXCEPT (SELECT shipments.isbn
FROM books, editions, shipments
WHERE books.book_id = editions.book_id AND
editions.isbn = shipments.isbn AND
title LIKE '%The Cat in the Hat%'));
I understand that this is hard to ask considering you don't have the database I'm using, but any help with this would be very much appreciated!
EDIT: I should add that there is two editions of 'The Cat in the Hat' in the database, both with different isbn's. So that has to be taken into account.
Use explicit JOIN syntax instead of mixing it with real conditions in where clause. I believe that this should work:
CREATE VIEW no_cat_customers(customer_first_name, customer_last_name) AS
SELECT first_name, last_name
FROM customers c
WHERE NOT EXISTS (
SELECT 1
FROM shipments s
JOIN editions e ON s.isbn = e.isbn
JOIN books b ON b.book_id = e.book_id
WHERE b.title ILIKE '%The Cat in the Hat%'
AND c.c_id = s.c_id
)
If you have datatype errors, cast your columns to appropriate types before comparing them.

SQL Slightly complicated query

Question: Write a query to find academics that are authors and that have only ever coauthored papers with authors from institutes in the same state as their own. List their academic number, title and last name.
I've been working on this question for some time and I haven't been able to think of a proper query.
My schema for the database (tables) I need to use:
ACADEMIC(ACNUM, DEPTNUM, FAMNAME, TITLE)
DEPARTMENT(DEPTNUM, STATE)
AUTHOR(PANUM, ACNUM)
There are multiple ACNUM's (Account number) for 1 PANUM (Page number) inside the Author table.
I tried planning it and all I could think of was something along the lines of this:
Need to loop through Author table,
SELECT PANUM
FROM AUTHOR A
Then need to find all authors of that paper:
SELECT ACNUM
FROM AUTHOR B
WHERE PANUM = A.PANUM;
Then need to intersect all states:
SELECT DEPTNUM, TITLE, FAMNAME, UPPER(STATE)
FROM ACADEMIC C, DEPARTMENT D
WHERE C.ACNUM = B.ACNUM AND D.DEPTNUM = C.DEPTNUM;
Could you guys give me some assistance on how I could do something like this? I appreciate any help.
EDIT: Some more information
I haven't actually figured out a desired result as theres hundreds of rows of data. Essentially, I have to query the database by: Selecting page number from Author table, then finding all Account Number's that the Author table has for that page number, then using all these account numbers I need to make sure they are all in the same state. E.g. Account 100 and 101 worked on page number 300 together and both are in state VIC, thus I would list the academics information (famname, title and acnum)
You need to query out a table joining the ACADEMIC, DEPARTMENT, and AUTHOR tables, and then self-join that table by paper, restricting on state, to obtain the result you want:
SELECT DISTINCT t1.FAMNAME, DISTINCT t1.TITLE FROM
(ACADEMIC a1 INNER JOIN DEPARTMENT d1 ON a1.DEPTNUM = d1.DEPTNUM
INNER JOIN AUTHOR auth1 ON a1.ACNUM = auth1.ACNUM) t1
INNER JOIN
(ACADEMIC a2 INNER JOIN DEPARTMENT d2 ON a2.DEPTNUM = d2.DEPTNUM
INNER JOIN AUTHOR auth2 ON a2.ACNUM = auth2.ACNUM) t2
GROUP BY t1.PANUM
HAVING COUNT(DISTINCT t2.STATE) = 1;

need help with mysql for book system - problem with where clause

hello all im developing new project for publisher ...this project for develop system saved all books for that publisher ...............
we have 3 table
books
author
coauthor
problem case:
ieach book have 1 main author thats author could replay in alot of books and ieach book in some cases could have co-author this co author could be 1 or 2 or 3 or 12 note: this co author is already saved in author table
realtionship:
one to many between authors and books
many to many between coauthor and books and authors
table #1 authors table => table hold all authors
id - author_name
table #2 books table => table hold all books
id- title - author_id - publishing_year
table #3 co_authors table => hold all item which have alot of co author
item_id and authors_id
now how i can retrive all books for specific author if he is main author or co author
There're two ways you can go about this... One is to use a UNION, so something like:
SELECT id FROM books WHERE author_id = ?
UNION ALL
SELECT item_id FROM co_authors WHERE authors_id = ?
Another way you could solve this is to rework your database structure such that there is no author_id in the books table and instead you have a flag in co_authors called main_author or some such. Considering you may have books where it's unclear who the main author is, this may make more sense...
You can do something like this :
SELECT DISTINCT books.*, authors.*
FROM books
LEFT JOIN co_authors ON co_authors.item_id = books.id
INNER JOIN authors ON
authors.id = books.author_id OR
authors.id = co_authors.author_id
WHERE authors.id = ID
The where clause can also be written where authors.name = 'NAME' if you need to search by name and not id.
EDIT: added distinct to avoid multiple rows for the same book.