Is it joins again in ORACLE - sql

Here's the problem:
List the title, authors first and last names and year to date sales for books whose authors have addresses in California and Utah.
the desc tables:
SQL> desc authors
Name
--------------------------
AUTHOR_ID
AUTHOR_LNAME
AUTHOR_FNAME
PHONE
ADDRESS
CITY
STATE
ZIP
SQL> desc title_authors
Name
--------------------------
AUTHOR_ID
TITLE_ID
AUTHOR_ORD
ROYALTY_SHARE
SQL> desc titles
Name
--------------------------
TITLE_ID
TITLE
TYPE
PUBLISHER_ID
PRICE
ADVANCE
YTD_SALES
CONTRACT
NOTES
PUBLICATION_DATE
Here's what Ive tried w/ results......
SQL> SELECT AUTHORS.AUTHOR_FNAME, AUTHOR_LNAME, TITLES.TITLE, TITLES.YTD_SALES
2 FROM AUTHORS
3 JOIN TITLE_AUTHORS ON AUTHORS.AUTHOR_ID = TITLE_AUTHORS.AUTHOR_ID
4 JOIN TITLES ON TITLE_AUTHORS.TITLE_ID = TITLES.TITLE_ID
5 WHERE STATE = 'CA'
6 OR STATE = 'UT';
AUTHOR_FNAME AUTHOR_LNAME TITLE YTD_SALES
-------------------- ---------------------------------------- ---------------------------------------- ----------
Marjorie GreeN The Busy Executive's Database Guide 4095
Marjorie GreeN You Can Combat Computer Stress! 18722
Dick StrAight Straight Talk About Computers 4095
Note 3 full results returned.
Next trial, which Ive tried various versions of, returns 3 full records, but the entire authors list:
AUTHOR_FNAME AUTHOR_LNAME TITLE YTD_SALES
-------------------- ------------ ---------------------------------------- ----------
Marjorie GreeN The Busy Executive's Database Guide 4095
Marjorie GreeN You Can Combat Computer Stress! 18722
Dick StrAight Straight Talk About Computers 4095
Albert Ringer
Ann Dull
JOHNSON White
Chastity Locksley
Anne RINGER
Stearns MacFeatHer
Anne RINGER
Michael O'Leary
Stearns MacFeatHer
Livia Karsen
Abraham BeNNet
Albert Ringer
Michael O'Leary
Sheryl Hunter
Cheryl Carson
Chastity Locksley
What is this? Is it blocked somehow? I can see the entire tables individually.
Any one?

Try this,
SELECT AUTHORS.AUTHOR_FNAME, AUTHOR_LNAME, TITLES.TITLE, TITLES.YTD_SALES
FROM AUTHORS
INNER JOIN TITLE_AUTHORS ON AUTHORS.AUTHOR_ID = TITLE_AUTHORS.AUTHOR_ID
INNER JOIN TITLES ON TITLE_AUTHORS.TITLE_ID = TITLES.TITLE_ID
WHERE STATE = 'CA' OR STATE = 'UT';

Related

Self JOIN to find the parent detail which matches with the row data -

I am trying to query in MS SQL and I can not resolve it. I have a table employees:
Id Name Surname FatherName MotherName WifeName Pincode isChild
-- ------- ------- ---------- ---------- -------- ------- -------
1 John Green James Sue null 101011 1
2 Michael Sloan Barry Lilly null 101011 1
3 Sally Green Andrew Molly Jemi 101011 1
4 Barry Sloan Soul Paul Lilly 101011 0
5 James Green Ned White Sue 101011 0
I want a query that selects rows where the father name and mother name of child matches with name and wife name. For the example table, where I want to return the result of rows where father and mother name matches the name and wife name column. For eg. id=1, where John's father name James and mother name Sue matches with id 5 which returns James as first name and Sue as wife name. So my query should return (this is my expected result)
Id Name Surname FatherName MotherName WifeName Pincode isChild
-- ------- ------- ---------- ---------- -------- ------- -------
5 James Green Ned White Sue 101011 0
4 Barry Sloan Soul Paul Lilly 101011 0
I tried with the below query but it checks for James only. How to change my query so that it checks all the names and returns the expected result.
select * FROM employees
where first_name like '%James%'
and wife_name like '%Sue%'
and pincode=101011;
Any tips on this will be really helpful. I am new to joins, need help on writing self join to get the result.
…
select *
from thetable as p -- the parent/father
where exists -- with one child at least
(
select *
from thetable as c
where c.fathername = p.name
and c.mothername = p.wifename
-- lastname?
)
Too long for a comment, but also not intended as a slam against what you are working with. Please take as constructive criticism.
Aside from VERY POOR DESIGN on the table content, getting that corrected before you get too deep into whatever you are working should be done first. A more typical design might be having a table of people. Now, to get the relationships you could do a couple ways. One is that on each individual person's record, you add 2 additional IDs. FatherID, MotherID. These IDs would join directly back to the child vs hard strings to match against. Take a surname like Smith or Jones. Then, look at the many instances of a "John Smith" may exist, yes a lot, and lower probability of finding a matching wife's name of Sue, Mary or whatever else name. But even that could lead to multiple possibilities. Yes, you are adding a PIN, but even a computer can generate a random pin of 1234.
By having the IDs, there is NO ambiguity of who the relationship is with.
If the data were slightly altered to something like
Id Name Surname FatherID MotherID SpouseID
-- ------- ------- ---------- ---------- --------
1 John Green 5 6 null
2 Michael Sloan 4 3 null
3 Lilly Sloan null null 4
4 Barry Sloan null null 3
5 James Green 9 10 6
6 Sue Green 7 8 5
7 Bill Jones null null 8
8 Martha Jones null null 7
9 Brian Green null null 10
10 Beth Smith-Green null null 9
So, in this modified example, you can see right away that ID#1 John Green has parents of Father (ID#5) is James and Mother (ID#6) is Sue. But even from this, James is a child to Father (ID#9) Brian and Mother (ID#10) Beth. This scenario is showing to a grand-parent level capacity and that each of James and Sue are also children but to their respective parents. Sue's parents of the Jones surname.
For Michael Sloan, parents of #4 Barry, and #3 Lilly.
And I additionally added a spouse ID. This prevents redundancy of people's names copied all over. Then you can query based on the child's parent's respective IDs to find out vs a hopeful name LIKE guess.
So, even though not solving a relatively simple query, fixing the underlying foundation of your database and is relations will, long-term, help ease your querying in the future.
Try this:
SELECT
T2.*
FROM Employee T1
JOIN Employee T2 ON T2.Name = T1.FatherName
AND T2.WifeName = T1.MotherName

oracle exercise question in my data using 2 table information

person
name home st
JAMES LA L1
MIKE BOSTON B1
ANTON LA L1
LEE NY N1
BROWN NY N2
mentor
name m_name
JAMES ANTON
MIKE (null)
ANTON (null)
LEE BROWN
BROWN (null)
I want to get information from people who live in the same st and cities as mentors.
In the example I gave, it is JAMES who meets that condition.
How could I get that information?..
my version oracle11g
This sounds like two joins:
select pn.name
from mentor m join
person pn
on pn.name = m.name join
person pm
on pm.name = m.m_name
where pn.street = pm.street and pn.city = pm.city;

Many to one merging sql

I have three tables as below:
First Table Second Table Third Table
Name PIN Id City City_id
David 1948 1 Roma 3
Susan 1245 2 Berlin 2
Jack 1578 3 New York 3
Hans 1247 2
Rose 8745 1
I want to merge first and second table according to third table. Result will be: Person
Name PIN City
David 1948 New York
Susan 1245 Berlin
Jack 1578 New York
Hans 1247 Berlin
Rose 8745 Roma
Firsty I can merge second and third table and then merge the result table with first table but I want to solve this problem without a medium table. How can I handle this? How can I combine first table's rows in sequence with a specified row in second table according to third table?
You would need a fourth table, PersonCity, with PersonID and CityID to link together. Think of relational databases like a grid (spreadsheet, roads). If you're going North and the street you want to get on is parallel (think |^| |^|) you're gonna need to use a different road that links the two. Currently, you have no such path.
The short answer is that your tables are not adequate for the task, what you need is along the lines of:
Table_1 Table_2 Table_3
Id Name PIN Id City Name_id City_id
1 David 1948 1 Roma 1 3
2 Susan 1245 2 Berlin 2 2
3 Jack 1578 3 New York 3 3
4 Hans 1247 4 2
5 Rose 8745 5 1
Then you can do your query as follow:
SELECT T1.Name, T1.PIN, T2.City
FROM Table_1 T1 LEFT JOIN Table_3 T2 ON T1.Id = T3.Name_id
LEFT JOIN Table_2 ON T3.City_id = T2.Id
ORDER BY T1.Name
Or you could ORDER BY City, name
I have good news and bad news.
The good news, Given the tables the way they were originally specified, in Oracle, this will give you something that looks like what you are asking:
---
--- Pay attention, This looks right but it is not!
---
select name,pin,city from
( select name,pin,rownum rn from first ) a,
( select city,id from second) b,
( select id,rownum rn from third ) c
where
a.rn=c.rn AND
b.id=c.id;
NAME PIN CITY
-------------------- ---- --------------------
Rose 8745 Roma
Susan 1245 Berlin
Hans 1247 Berlin
David 1948 New York
Jack 1578 New York
The bad news is this does not really work and is cheating. You will get results but they may not be what you would expect and they won't necessarily be consistent.
The database orders records in its own order. If you don't specify an order by clause, you get what they give you, which may not be what you want. This is cheating because Oracle does not REALLY support using rownum in this way because you can't bet on what you will get. This won't work in most other databases.
The only correct way is what #daShier gave, where you have to add something, say, ID, to allow connecting the rows in the order you want.

Sql about find rate is less then 9 and star name

Find every time a student paid 9 or less to see a movie starring Will Smith. Print all the relevant information; order by the name of the student (desc) and then the name of the movie.
there is two table one is call films has student name and amount_paid, movie_name and rate. another table name is movies, has movie_name and star.
Select star, movie_name, amount_paid, rate,
From movies
Where amount_paid < = 9
having star = 'will smith'
Order by student_name desc;
films
STUDENT_NAME MOVIE AMOUNT_PAID RATE
-------------------------- -------------------------- ----------- ----------
Jack Noah 12 5
Jet The Professional 24 10
Lincoln The Weather Man 10 4.5
Smith Despite the Falling Snow 9 3.5
River The Weather Man 2.5 4.5
PHIL FORREST GUMP 18 9
Dave Legend 18 8
movies
MOVIE_NAME STAR
-------------------------- --------------------------
Noah Russell Crowe
Legend will smith
You have an extra comma at the end of line one, and a gap between < and =.
Although trailing commas is okay in JSON, etc, it causes syntax errors in SQL.
And < = instead of <= is likely to break every programming language.
Select star, movie_name, amount_paid, rate -- removed a comma
From movies
Where amount_paid <= 9 -- removed a space
and star = 'will smith'
Order by student_name desc;
EDIT:
As this is from two tables...
SELECT
movies.STAR,
movies.MOVIE_NAME,
films.STUDENT_NAME,
films.AMOUNT_PAID,
films.RATE
FROM
films
INNER JOIN
movies
ON movies.MOVIE_NAME = films.MOVIE
WHERE
films.RATE <= 9
AND movies.STAR = 'will smith'
ORDER BY
films.STUDENT_NAME DESC
this will work:
SELECT
movies.STAR,
movies.MOVIE_NAME,
films.STUDENT_NAME,
films.AMOUNT_PAID,
films.RATE
FROM
films,
movies
where
films.movie=movies.movie_name
and films.AMOUNT_PAID>=9
order by films.STUDENT_NAME,movies.movie_name

How to solve this using a subquery in a from clause?

Display author, title, retail and retail price of all books whose retail price is the highest for the specific author.
I have the query below. I'm kinda confused how to do a subquery in a from clause.
select lname, fname, title, retail
from author natural join bookauthor
natural join books
where retail=(select max(retail)
from books);
Below is the data from the database that I'm using
FNAME LNAME TITLE RETAIL
---------- ---------- ------------------------------ ----------
SAM SMITH BODYBUILD IN 10 MINUTES A DAY 30.95
LISA PORTER BODYBUILD IN 10 MINUTES A DAY 30.95
JANICE JONES REVENGE OF MICKEY 22
TAMARA KZOCHSKY BUILDING A CAR WITH TOOTHPICKS 59.95
TINA PETERSON DATABASE IMPLEMENTATION 55.95
JUAN ADAMS DATABASE IMPLEMENTATION 55.95
JAMES AUSTIN DATABASE IMPLEMENTATION 55.95
JACK BAKER COOKING WITH MUSHROOMS 19.95
JAMES AUSTIN HOLY GRAIL OF ORACLE 75.95
LISA WHITE HANDCRANKED COMPUTERS 25
WILLIAM WHITE HANDCRANKED COMPUTERS 25
JANICE JONES E-BUSINESS THE EASY WAY 54.5
ROBERT ROBINSON PAINLESS CHILD-REARING 89.95
OSCAR FIELDS PAINLESS CHILD-REARING 89.95
JACK BAKER PAINLESS CHILD-REARING 89.95
SAM SMITH THE WOK WAY TO COOK 28.75
ROBERT ROBINSON BIG BEAR AND LITTLE DOVE 8.95
SAM SMITH HOW TO GET FASTER PIZZA 29.95
WILLIAM WHITE HOW TO MANAGE THE MANAGER 31.95
LISA WHITE SHORTEST POEMS 39.95
20 rows selected.
You could use this:
SELECT lname, fname, title, retail
FROM author a
INNER JOIN bookauthor ba
ON a.id = ba.author_id
INNER JOIN books b
ON b.id = ba.book_id
WHERE (ba.author_id, ba.retail) IN (
SELECT ba1.author_id, MAX(b1.retail)
FROM books b1
INNER JOIN bookauthor ba1
ON ON b1.id = ba1.book_id
GROUP BY ba1.author_id
);
Do not use NATURE JOIN. This is bad way of join, for all learner and programmer.
(And change author_id, book_id to column name of your specific table)
Other way:
SELECT lname, fname, title, retail
FROM author a
INNER JOIN bookauthor ba
ON a.id = ba.author_id
INNER JOIN books b
ON b.id = ba.book_id
INNER JOIN(
SELECT ba1.author_id, MAX(b1.retail) retail
FROM books b1
INNER JOIN bookauthor ba1
ON ON b1.id = ba1.book_id
GROUP BY ba1.author_id
) mr
ON
ba.author_id = mr.author_id
AND ba.retail = mr.retail
;
This can be solved using ether an inner join:
select lname, fname, title, retail
from author natural join bookauthor
natural join books
inner join (select max(retail) as max_retail, authorid
from books
group by authorid) b
on books.authorid = b.authorid and books.retail = b.max_retail
or a correlated subquery:
select lname, fname, title, retail
from author natural join bookauthor
natural join books
where retail=(select max(retail)
from books b where b.authorid=author.authorid);
Please note, because you are using the natural join it is impossible for us to know the actual column names you used for the joins. Therefore I have assumed that the authorid foreign key is called authorid