Create a relation - sql

I have no idea about how to create relation and solve their queries. I want to relation as follows:
BookAuthor(book, author, earnings)
BookReference(book, referenceBook, times)
BookReview(book, reviewer, score)
BookPublih(book, year, publisher, price, numbar)
In these database, each book may have 1 or more authors & each author may make a diff. amt. of money from that book. One book may make reference to other book.1 book may be reviewed by diff. reviewers and get diff. scores. an author could also be a reviewer & a publisher.
I want to solve following queries
Find all books published in 2003 & reviewed by both Sammer Tulpule & Hemant Mehta.
Find all the reviewers who never reviewed their own books.
Find all authors who reviewed more than 2 books written by Sita Mitra.
Find all authors who have written exactly 1 book and reviewed more than 1 book.
Find all the reviewer who reviewed every book from 'Stephen King'.
Find all books published in 1995-2000 in descending order.
I know, these is not good to find an answer, but believe me i really don't under

A solution to your problem could use these tables:
BOOKS (BookID, BookName,PubDate,PublisherPerson_ID,Price,Number) //stores each book and its data
PERSONS(PersonID, Name) //stores any people (authors, reviewers)
BOOKAUTHORS(Book_ID, Person_ID) //many to many relationship between books and authors
BOOKREVENUE(Book_ID, Person_ID, Revenue) //stores revenue for each book per author
BOOKREFERENCES(Book_ID, RefBook_ID) //many to many reference table for books
BOOKREVIEWERS(Book_ID, Person_ID, Score) //many to many relationship for book reviews
Im not going to write the queries here, but this will get you started

Related

How to summarize many to many relationship to output column in SQL

I have tables books, authors and books_authors in a many to many relationship.
What I want to do is select all books AND add a column to the output with a string of the authors ids for each book. I know how to do the joins to find the authors for each book but that gives me x many rows for each book as there are authors for that book. I want one row per book. Thanks

Finding duplicate rows with unique keys in table

I'm grabbing some text data from a table and having trouble figuring out how to do this exactly.
My data is book information. I have author, book title, and a book summary. Some of the summaries were duplicated into other book titles. So, for example:
Author: David Smith
Book Title: SQL For Dummies
Summary: A great book about SQL.
Author: David Smith
Book Title: Dummies Don't Need SQL
Summary: A great book about SQL.
Author: Jim Jones
Book Title: We Don't Use SQL Here
Summary: This book says you should not use SQL.
What I'm looking for is a way to get the author, book title and summary for the duplicates and tie them to each other. So I'd see the author and book titles for both books that have a duplicate summary, grouped together.
I'm using an oracle database server.
I've wracked my brain for hours and am not sure where to look next. Thanks!
select *
from (
select
summary, author, title,
count(*) over (partition by summary) cnt
from your_table
)
where cnt>1
order by summary, author, title
Also you can use dense_rank to mark groups

How to combine two databases?

I am asking myself how to best define a new database given two databases.
I have the following two databases
Author where I save information about authors i.e. Name, Birthyear, Country, Genre etc.
Book where I save information about the book i.e. AuthorName, ReleaseYear, Pages etc
How do I create a new database with the full information about all books and the author? I.e. a Book_Complete Database which includes Author.Name, ReleaseYear,Pages, Genre,ReleaseYear and Author.Birthyear, Author.Country?
Better to go for a single database and having 2 tables in it like
Author Table
AuthorId (PK)
Name
Birthyear
Country
Genre
Book Table
BookId (PK)
AuthorId (FK)
ReleaseYear
Pages
If you have two tables in a database you can combine them using JOIN. Here is SQLite tutorial on how to use JOIN.
https://www.sqlitetutorial.net/sqlite-join/
On the information you provided I assume you can you columns Name in table Author, and AuthorName in table Book. You can try something like this
SELECT
A.Name,
B.ReleaseYear,
B.Pages,
B.Genre,
B.ReleaseYear,
A.Birthyear,
A.Country
FROM
Author A
LEFT JOIN Book B
ON A.Name = B.AuthorName
Basically, I have these create these two tables on my app and want to store the combined version on a server. Or would you suggest another approach?
Yes we would. You should have one table per entity, i.e. one for the authors and one for the books. Thus you don't store data redundantly (e.g. the author's name or the book's title), which could otherwise lead to inconsistencies later. You can read up on database normalization here: https://en.wikipedia.org/wiki/Database_normalization or google it.
Now you must decide how to link the tables. One author can write multiple books. Can one book be written by multiple authors? Give both tables IDs you can work with (or find some natural unique key, like the ISBN for the book and maybe name + birth year for the author - the name only will probably not suffice and maybe it won't even when combined with the year).
If one book can only be written by one author, you have a 1:n relation (one book written by one author, one author writing multiple books).
author (author_id, name, birth_year, country, ...)
book (book_id, title, author_id, release_year, pages, ...)
If one book can have several authors, you have an m:n relation (one book written by multiple authors, one author writing multiple books).
author (author_id, name, birth_year, country, ...)
book (book_id, title, release_year, pages, ...)
book_author (book_id, author_id)
You can always join the tables, so as to get a combined result.

SQL count column rows that is dependent on a column in different table when group by

I have been trying to complete the following assignment:
Write a query that returns authors who've written books in more than one category and whose books are published by at least two different publishers. Display the author's Last Name and First Name, the Titles of Books they've written and the Book type. Sort the output by the author's last name.
These are the tables involved:
AUTHORS (Au_id, Au_lname, Au_fname, Phone, Address, City, State, Country, Postalcode)
PUBLISHERS (Pub_id, Pub_name, City, State)
TITLES (Title_id, Title, Type, Pub_id, Price, Advance, Total_sales, Notes, Pubdate, Contract)
TITLEAUTHOR (Au_id, Title_id)
I was able to identify the columns I need, but am not sure how to implement the filters (2 different authors, 2 different types). I assume I need to group by author id and count the Pub_id and Type columns.
This is what I have written so far:
SELECT AUTHORS.Au_lname, AUTHORS.Au_fname, TITLE.Title_id, TITLE.Type
from AUTHORS
JOIN TITLEAUTHOR ON AUTHORS.Au_id = TITLEAUTHOR.Au_id
JOIN TITLE ON TITLEAUTHOR.Title_i = TITLE.Title_i
group by AUTHORS.Au_lname, AUTHORS.Au_fname, TITLE.Title_id, TITLE.Type
ORDER BY AUTHORS.Au_lname;
Welcome to Stack Overflow, Tomasz! Congratulations on your first post. You've done a couple of excellent things already:
You included details on your schema
You included a clear problem statement
You included an example of the SQL you have already tried.
There are a couple of ways you could improve your post, which would help your chances of getting a good answer while also boosting your ability to participate in the community:
Be very careful with formatting - your second edit introduced some redundant text.
Be particular with your code - the first set you gave had some incorrect column names, which likely caused some users to look at your post and then ignore it. There's a critical window after you first post a question where it shows up near the top of the list; that's your best shot at getting answers, so it pays to be very careful with your presentation. Here's a link to some good reading on how to ask.
Be upfront about it when you're working on an assignment! As you can imagine, this community gets a lot of requests for help on homework. Many of the regular users get frustrated by people looking to 'cheat' on their assignments by posting their homework online. There are ways to get help, though: read this post over carefully so you're ready for your next question. The keys are to show that you've already tried to solve it yourself, be specific about what's not working, and be clear about the fact that this is homework.
Now, about your question! What you are looking for is the HAVING clause, which allows you to filter a query to return only those members of a group who meet a condition at the aggregate level. Your instinct about a COUNT was right on, and the HAVING clause will let you do that. Here's an example:
SELECT Au_id
FROM
AUTHORS
INNER JOIN
TITLEAUTHOR ON
AUTHORS.Au_id = TITLEAUTHOR.Au_id
INNER JOIN
TITLES ON
TITLEAUTHOR.Title_id = TITLE.Title_id
GROUP BY Au_id
HAVING
COUNT(DISTINCT TITLES.pub_id) > 1 AND
COUNT(DISTINCT TITLES.Type) > 1
Notice that this adds the word DISTINCT inside of the COUNT() function - this helps you meet the "two different publishers" requirement.
Once you understand how to use HAVING, then you can write a query to get the columns your assignment asked for, and filter the set to only return authors you want: the basic query structure is going to look like this:
SELECT MyColumns
FROM MyTables
WHERE Au_id IN
(
SELECT Au_id
FROM
AUTHORS
INNER JOIN
TITLEAUTHOR ON
AUTHORS.Au_id = TITLEAUTHOR.Au_id
INNER JOIN
TITLES ON
TITLEAUTHOR.Title_id = TITLE.Title_id
GROUP BY Au_id
HAVING
COUNT(DISTINCT TITLES.pub_id) > 1 AND
COUNT(DISTINCT TITLES.Type) > 1
)
ORDER BY WhateverYouWant
Good luck, and welcome to SQL!

Issues with Group functions

I'm working on lab question that I just cannot come up with a solution, that would allow me to figure out the books that have more then one author(See the posted question below for my comments to make sense). My mind is totally blank on it. I'm very bad with word problems. I know that I have to do a JOIN statement which I've completed and I know that I have to use the COUNT function to count the number of authors but I honestly don't know how I would go about only counting the books that have 2 authors.
Any input would be appreciated. I tried to break it down into steps but it's just that one part that I'm not grasping in my mind.
Using the correct tables in your schema, create a query using either join operation you wish that will list the book title and number of authors for all books that have been written by more than one author. Give the title column an alias of "Book Title" and the column showing the number of authors an alias of "Number of Authors".
There is a BOOKS table and a AUTHOR table that are JOINED by a BOOK_AUTHOR table by their BOOKID in BOOKS and AUTHORID in AUTHOR.
I think I'm starting to understand that I have to use a mathematical equation to figure out more then one author. I don't understand the HAVING function all too well so I'm going to do more research on this one.
You were right, you need a JOIN, a COUNT, but also an HAVING to make sure there is more then one authors that written the book :
select title as 'Book Title', count(authors) as 'Number of Authors'
from books
join authors on books.id = authors.book_id
having count(authors) > 1
group by authors;
Make sure to adapt the table names and columns to the right one, as you didn't post them.
Note that if the books's author id column has the same name as the author id, you can use the USING keyword to join. then your query would become
select title as 'Book Title', count(authors) as 'Number of Authors'
from books
join authors on using(book_id)
having count(authors) > 1
group by authors;
Note that if you want to select only books that specifically have 2 authors you can change the having clause to having count(authors) = 2. But even if you ask for that in your question, according to the exercice you pasted, you did not understand properly the question.
I finally figured out the answer with all your help. Please see below:
SELECT DISTINCT Title "Book Title", COUNT(*)"Number of Authors"
FROM BOOKS JOIN
BOOK_AUTHOR ON
BOOKS.BookId = BOOK_AUTHOR.BookId
JOIN AUTHOR ON
BOOK_AUTHOR.AuthorId = Author.AuthorId
GROUP BY Title
HAVING COUNT(*) > 1;