SELECT COLUMNS FROM INNER JOIN - sql

I wanted to select two columns from inner join of two select queries. I have written a query joining three tables and from the result I want to get only two column. But my query is showing error.I am using oracle sql developer.
SELECT firstname,surname
FROM (
SELECT A.firstname,A.surname,I.ACNUM,I.FIELDNUM
FROM ACADEMIC A INNER JOIN INTEREST I
ON (A.ACNUM = I.ACNUM)
INNER JOIN SUBJECT S ON (I.FIELDNUM = S.FIELDNUM) WHERE S.TITLE = 'History' ) ;
I want only the firstname and surname but I am getting error like:
Incorrect syntax near ';'.

Why are you using a subselect? Just use:
SELECT A.firstname, A.surname
FROM ACADEMIC A INNER JOIN
INTEREST I
ON A.ACNUM = I.ACNUM INNER JOIN
SUBJECT S
ON I.FIELDNUM = S.FIELDNUM
WHERE S.TITLE = 'History' ;

When you select from query you should name it as well.
Try this:
SELECT D.firstname,D.surname
FROM (SELECT A.firstname,A.surname,I.ACNUM,I.FIELDNUM
FROM ACADEMIC A
INNER JOIN INTEREST I ON (A.ACNUM = I.ACNUM)
INNER JOIN SUBJECT S ON (I.FIELDNUM = S.FIELDNUM)
WHERE S.TITLE = 'History') D;

Related

SQL question on correlated sub-queries using windowing rank functions

I have this SQL homework assignment that tells me to list all the customers and the most recent DVD which they have rented, including the title, Genre, Rating, DVD and date of rental. This can be solved via a correlated sub-query or a window rank function
Here is a screenshot of the schema:
Here is what I have tried so far:
Select
Concat(m.MemberFirstName, ' ', m.MemberLastName) as Member
, d.DvdTitle
, g.GenreName
, rt.RatingName
, r.RentalRequestDate
From
Member m
Inner Join
RentalQueue rq on m.MemberId = rq.MemberId
Inner Join
DVD d on d.DVDId = rq.DVDId
Inner Join
Genre g on g.GenreId = d.GenreId
Inner Join
Rating rt on rt.RatingId = d.RatingId
Inner Join
Rental r on r.DVDId = d.DVDId
I am not sure how I can use correlated subqueries to answer the question above as I am quite new to correlated subqueries and I would appreciate some help on this. Thanks in advance.
Try something like this, but please try to understand it too.
Select
Concat(m.MemberFirstName, ' ', m.MemberLastName) as Member
, mostrecent.*
From
Member m
CROSS APPLY
(select top (1)
d.DvdTitle
, g.GenreName
, rt.RatingName
, r.RentalRequestDate
FROM
RentalQueue rq
Inner Join
DVD d on d.DVDId = rq.DVDId
Inner Join
Genre g on g.GenreId = d.GenreId
Inner Join
Rating rt on rt.RatingId = d.RatingId
Inner Join
Rental r on r.DVDId = d.DVDId
where m.MemberId = rq.MemberId
order by r.RentalRequestDate desc
) mostrecent

sqlite: count and group by clause gives not the result expected

on sqlite, I have the tables
papers: rero_id, doi, year
writtenby: rero_id, authorid, instid
authors: author_id, name, firstname
inst: inst_id, name, see_id
inst is a table of Institutions: Universities and so on.
Each line in writtenby gives a paper, an author, an institution this author was attached at that time. There can be more then one institution and the couple paper, authorid is repeated for each institution.
For a given author, I want a list and a count of the institutions he has cohautored paper with.
For a list I tried
SELECT inst.name as loc
FROM (
(authors INNER JOIN writtenby ON authors.authorid =
writtenby.authorid)
INNER JOIN writtenby AS writtenby_1 ON writtenby.rero_id =
writtenby_1.rero_id
)
INNER JOIN authors AS auth_1 ON writtenby_1.authorid =
auth_1.authorid
inner join inst on writtenby_1.instid = inst.inst_id
WHERE (authors.name) ="Doe" AND (authors.firstname)= "Joe"
ORDER BY loc
I got a list that seems ok.
Now, I would like to regroup these institution names and have a count.
I tried
SELECT inst.name, count(inst.name)
FROM (
(authors INNER JOIN writtenby ON authors.authorid =
writtenby.authorid)
INNER JOIN writtenby AS writtenby_1 ON writtenby.rero_id =
writtenby_1.rero_id
)
INNER JOIN authors AS auth_1 ON writtenby_1.authorid =
auth_1.authorid
inner join inst on writtenby_1.instid = inst.inst_id
GROUP BY inst.name
HAVING (authors.name) ="Doe" AND (authors.firstname)= "John"
I have only three line and not a count of the institutions listed from the first query.
Thanks for correcting me !
François
Try using where instead of having
SELECT inst.name, count(inst.name)
FROM (
(authors INNER JOIN writtenby ON authors.authorid =
writtenby.authorid)
INNER JOIN writtenby AS writtenby_1 ON writtenby.rero_id =
writtenby_1.rero_id
)
INNER JOIN authors AS auth_1 ON writtenby_1.authorid =
auth_1.authorid
inner join inst on writtenby_1.instid = inst.inst_id
where authors.name ='Doe' AND authors.firstname= 'John'
GROUP BY inst.name
I got this that works,
SELECT inst.name as loc, count(*) as c
FROM (
(authors INNER JOIN writtenby ON authors.authorid = writtenby.authorid)
INNER JOIN writtenby AS writtenby_1 ON writtenby.rero_id =
writtenby_1.rero_id
inner join inst on writtenby_1.instid = inst.inst_id
)
INNER JOIN authors AS auth_1 ON writtenby_1.authorid = auth_1.authorid
WHERE (authors.name) ="Doe" AND (authors.firstname)= "John"
GROUP BY inst.name
ORDER BY c DESC
I still can use a where clause, and that's not the same as having...
And thanks to fa6 who gave the answer below
F.

SQL subselect group function not allowed

I'm facing a problem with an SQL subquery: I need to write a query which returns the courses where the number of subscriptions (count(employeeNumber)) is greater than the maximum allowed number of subscriptions (Maximum).
In my original query I'm getting following error:
Group function is not allowed here.
The query:
SELECT c.CourseName
FROM courses c
INNER JOIN subscriptions s ON s.courseCode = c.CourseCode
INNER JOIN plannedCourses p ON p.CourseCode = s.CourseCode
WHERE COUNT(s.EmployeeNumber) > (SELECT maximum
FROM plannedCourses
WHERE s.CourseCode = p.CourseCode);
The table layout:
How can i achieve the desire result?
Thanks in advance!!
You could rewrite your query as follows:
select c.coursename
from courses c
join subscriptions s
on (s.coursecode = c.coursecode)
join PlannedCourses p
on (p.coursecode = c.coursecode)
group by c.coursename
, p.maximum
having count(s.Employeenumber) > p.maximum
Your query has multiple problems. You are using a correlated subquery, but you are not using the table in its from clause. I think the intention is this:
SELECT c.CourseName
FROM courses c
INNER JOIN subscriptions s ON s.courseCode = c.CourseCode
group by c.CourseName, c.CourseCode
having COUNT(s.EmployeeNumber) > (SELECT "maximum"
FROM plannedCourses p
WHERE c.CourseCode = p.CourseCode);

SQL Inner join division

I have issue with my inner join division below. From my oracle, it keep prompt me missing right parenthesis when I have already close it. I'll need to get the names of the patient who have collected all items.
Select P.name
From ((((Select Patientid From Patient) As P
Inner Join (Select Accountno, Patientid From Account) As A1
on P.PatientID = A1.PatientID)
Inner Join (Select Accountno, Itemno From AccountType) As Al
On A1.Accountno = Al.Accountno)
Inner Join (Select Itemno From Item) As I
On Al.Itemno = I.Itemno)
Group By Al.Itemno
Having Count(*) >= (Select Count(*) FROM AccountType);
Here's a simpler approach that I believe is essentially equivalent:
select a.name
from Patient a
inner join Account b on a.PatientID = b.PatientID
inner join AccountType c on b.Accountno = c.Accountno
inner join Item d on c.Itemno = d.Itemno
group by c.Accountno, a.name
having Count(*) >= (Select Count(*) FROM AccountType);
This approach is a bit simpler. It has the added benefit of being much more likely to use indexes on the tables -- if you do joins between what are essentially 'join tables' in memory, you don't get the benefit of the indexes that exist for the physical tables in memory.
I also usually alias table names using sequential letters -- 'a', 'b', 'c', 'd' as you can see. I find that when I'm writing complicated queries it makes it easier for me to follow. 'a' is the first table in the join, 'b' is the second, etc.
It sounds like you just want
SELECT p.name
FROM patient p
INNER JOIN account a ON (a.patientID = p.patientID)
INNER JOIN accountType accTyp ON (accTyp.accountNo = a.accountNo)
INNER JOIN item i ON (i.itemNo = accTyp.itemNo)
GROUP BY accTyp.itemNo
HAVING COUNT(*) = (SELECT COUNT(*)
FROM accountType);
Note that having an alias of A1 and an alias of Al is quite confusing. You want to pick more meaningful and more distinguishing aliases.

SQL query on table that has 2 columns with a foreign id on the same table

I have a table let's say in the form of: match(id, hometeam_id, awayteam_id) and team(id, name). How do I build my SQL query in order to get a result table in the form of (match_id, hometeam_name, awayteam_name), since they both (hometeam_id, awayteam_id) reference the same table (team)?
Thank you
You would just join to the team table multiple times:
SELECT m.id, away.name, home.name
FROM match m
INNER JOIN team away ON away.id = m.awayteam_id
INNER JOIN team home ON home.id = m.hometeam_id
You join to the team table twice.
select matchdate, t1.teamname, t2,teamname from
match m
join team t1 on m.hometeamId = t1.teamid
join team t2 on m.awayteamid = t2.teamid
Join to the team table twice, once for the Home Team, and again for the Away Team, using aliases after the table names in the query:
select m.match_id, homeTeam.name as HomeTeamName, awayTeam.name as AwayTeamName
from
team homeTeam join
match m on m.hometeam_id = homeTeam.hometeam_id join
team awayTeam on awayTeam.hometeam_id = m.awayteam_id
select m.id, h.name as hometeam_name, a.name as awayteam_name
from match m left join team h on m.hometeam_id = h.id
left join team a on m.awayteam_id = a.id