A self join query - sql

Given this relational schema
people (pid, name, gender, age, email, city, state)
books (ISBN, title, edition, publisher, year, rating)
write (pid, ISBN) pid is a foreign key and refers to people (pid), ISBN is a foreign key and refers to books (ISBN)
I need to write a SQL query to find the authors who either never published co-authored books or only co-authored with others from the same state, return their names.
I know I need to use a self join but not sure how to do that.
Thanks!

I think Tim's reasoning is correct, but the query is not. It requires a self-join on writes:
select p.*
from people p
where not exists (select 1
from writes w join
writes w2
on w.isbn = w2.isbn join
people p2
on w2.pid = w.pid
where w.pid = p.pid and
p.state <> p2.state
);

Your two logical criteria can actually be condensed into saying that you only want authors who have not coauthored books with other from different states. So, we can write a query for that:
SELECT p1.name
FROM people p1
WHERE NOT EXISTS (SELECT 1 FROM write w INNER JOIN people p2 ON p2.pid = w.pid
WHERE w.pid = p1.pid AND p2.state <> p1.state);

Related

How to use Sql join to include a specific column from another table

I have two tables, author and book. Author contains the columns (isbn, name, city, state) and book contains (isbn, title, publisher, category, price, units)
For my assignment I need to output name, city and state (from the author table) and title (from the book table) only for authors from Exeter, NH, Palo Alto, CA, or Arlington, TX.
I can't get join part to work without an error popping up
SELECT
NAME,
city,
state
FROM
author
left JOIN book
USING (title);
WHERE
(city = 'exeter'AND state = 'NH') OR
(city = 'arlington'AND state = 'TX') OR
(city ='palo alto' AND state = 'CA');
What is your DBMS?
you need a field to relate the 2 tables, I suppose it is the ISBN that is the only one in common... (although as they already asked you why the ISBN is in the author?)...
SELECT a.NAME, b.title,a.city,a.state
FROM author a
LEFT JOIN book b
ON a.isbn = b.isbn
WHERE (a.city = 'exeter'AND a.state = 'NH')
OR (a.city = 'arlington'AND a.state = 'TX')
OR (a.city ='palo alto' AND a.state = 'CA')
Left outer join should work so long as you join on the columns shared by the tables.
SELECT a.name
,a.city
,a.state
,b.title
FROM author a
LEFT OUTER JOIN book b on a.isbn = b.isbn
WHERE

At most one query SQL

I'm doing some exercises in a basic SQL and I have the following problem:
Let us consider the following relational schema about actors and films:
Film: FilmCode đŸ”‘, Title, Filmmaker, Year
Actor: ActorCode đŸ”‘, Surname, Name, Sex, BirthDate, Nationality
Interpretation: Film, Actor, Role
Let us assume that more than one actor may act in a film and that the same actor may act in more than one film and in a given film, each involved actor plays only one role.
Filmmaker to be univocally identified by his/her surname and each film to be directed by a single filmmaker.
The query I have to write is:
the actors that acted together in at most one film directed by the filmmaker Quentin Tarantino.
How can I translate the "at most one film" into SQL language?
What I have wrote so far is:
SELECT DISTINCT A1.ActorCode, A2.ActorCode
FROM Actor A1 A2, Interpretation I1 I2
WHERE I1.Film=I2.Film and I1.Actor <> I2.Actor and A1.ActorCode= I1.Actor and A2.ActorCode=I2.ActorCode and exists unique (
Select *
From Film F
Where I1.Film=F.FilmCode and F.Filmmaker=’Tarantino’
)
But that's not the point
SELECT
I.Actor, I2.Actor
FROM Interpretation I
INNER JOIN FIlm F
ON F.Filmmaker=’Tarantino’
and F.FilmCode = I.Film
INNER JOIN Interpretation I2
ON I.Film = I2.Film
and I2.Actor <> I.Actor
and I2.Actor not in (SELECT Actor
FROM Interpretation I3
INNER JOIN FIlm F1
ON F1.Filmmaker=’Tarantino’
and F1.FilmCode = I3.Film
and F1.FilmCode <> I.Film #All other tarantino films
WHERE I3.Actor = I.Actor)

PostgreSQL: How do I get data from table `A` filtered by a column in table `B`

I want to fetch all parents that have kids in a specific grade only in a school.
Below are trimmed down version of the tables.
TABLE students
id,
last_name,
grade_id,
school_id
TABLE parents_students
parent_id,
student_id
TABLE parents
id,
last_name,
school_id
I tried the below query but it doesn't really work as expected. It rather fetches all parents in a school disregarding the grade. Any help is appreciated. Thank you.
SELECT DISTINCT
p.id,
p.last_name,
p.school_id,
st.school_id,
st.grade_id,
FROM parents p
INNER JOIN students st ON st.school_id = p.school_id
WHERE st.grade_id = 118
AND st.school_id = 6
GROUP BY p.id,st.grade_id,st.school_id;
I would think:
select p.*
from parents p
where exists (select 1
from parents_students ps join
students s
on ps.student_id = s.id
where ps.parent_id = p.id and
s.grade_id = 118 and
s.school_id = 6
);
Your question says that you want information about the parents. If so, I don't see why you are including redundant information about the school and grade (it is redundant because the where clause specifies exactly what those values are).

SQL query to filter value using associative entity

I'm working on this educational system in which the professor table stores the subject ID, career and subject are stored in their own tables and I have the career_subject associative entity because the system assume that the same subject may belong to several careers. The tables look something like this:
CAREER(id, name, quota)
SUBJECT(id, name, exam_date)
PROFESSOR(id, name, subject_id)
CAREER_SUBJECT(career_id, subject_id)
So, how do I get the name of the career the professor may teach using SQL?
I'm trying with
SELECT name FROM career
INNER JOIN career_subject ON career_subject.subject_id = career_subject.subject_id
WHERE professor.subject_id = subject.id;
SELECT p.name as 'Professor', c.name as 'Career' FROM professor p
INNER JOIN career_subject cs ON cs.subject_id = p.subject_id
INNER JOIN career c ON c.id = cs.career_id

SQL Query Using Data from 2 tables

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')