oracle exercise question in my data using 2 table information - sql

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;

Related

How to join two tables with three pairs

I have two tables that I want to combine (join) in SQL.
Table 1 Persons:
Person _Id
First_name
Last_name
135790
John
Smith
246801
Lucas
Williams
054953
George
Johnson
460235
Adam
White
Table 2 Loans:
Borrower_Id
resident1_id
resident2_id
135790
246801
054953
460235
054953
135790
054953
246801
135790
The expected result:
Borrower_FN
Borrower_LN
resident1_FN
resident1_LN
resident2_FN
resident1_LN
John
Smith
Lucas
Williams
George
Johnson
Adam
White
George
Johnson
John
Smith
George
Johnson
Lucas
Williams
John
Smith
How can I join it?
This is a way you can achieve the result:
select p.First_name as Borrower_FN, p.Last_name as Borrower_LN,
p2.First_name as resident1_FN, p2.Last_name as resident1_LN,
p3.First_name as resident2_FN, p3.Last_name as resident2_LN
from Loans l
inner join Persons p on p.Person_id = l.Borrower_id
inner join Persons p2 on p2.Person_id = l.resident1_id
inner join Persons p3 on p3.Person_id = l.resident2_id

SQL join manager from same table onto a row with their employees

To start, here's a dummy table I've made to show the data I'm working with:
employee
title
division
email
Boss Person
boss
o
bp#email
John Smith
supervisor
a
jos#email
Jane Smith
supervisor
b
jas#email
Leo Messi
employee
a
lm#email
Amanda Kessel
employee
a
ak#email
Derek Jeter
employee
b
dj#email
I want to end up with the following info:
employee
title
division
email
supervisor_name
supervisor_email
Boss Person
boss
o
bp#email
NULL
NULL
John Smith
supervisor
a
jos#email
Boss Person
bp#email
Jane Smith
supervisor
b
jas#email
Boss Person
bp#email
Leo Messi
employee
a
lm#email
John Smith
jos#email
Amanda Kessel
employee
a
ak#email
John Smith
jos#email
Derek Jeter
employee
b
dj#email
Jane Smith
jas#email
I've looked through and tried documentation at:
https://www.sqltutorial.org/sql-self-join/
SQL Server : LEFT JOIN EMPLOYEE MANAGER relationship
One of the big differences here is I don't have any employee or manager id column to work with.
If you're a supervisor for a division, ie John Smith is a supervisor in division a, then you manage all the employees in division a. Meanwhile, all the supervisors answer to the boss in division o, while the boss answers to no one.
Here is the best code I've tried so far:
select e.*, b.employee as supervisor, b.email as supervisor_email
from employees e, employees b
where b.division = e.division
and
b.title like '%supervisor%'
This got me close, it returned:
employee
title
division
email
supervisor_name
supervisor_email
John Smith
supervisor
a
jos#email
John Smith
jos#email
Jane Smith
supervisor
b
jas#email
Jane Smith
jas#email
Leo Messi
employee
a
lm#email
John Smith
jos#email
Amanda Kessel
employee
a
ak#email
John Smith
jos#email
Derek Jeter
employee
b
dj#email
Jane Smith
jas#email
So, it got the employee info right, but left out the Boss record and placed the supervisors as their own supervisor. I think I need some kind of case or if statement here, but I'm not sure.
Please let me know if this makes sense or if any further clarification is needed.
You could try using a LEFT JOIN and work with two conditions:
when division is the same and we're dealing with the relationship employee < supervisor
when the relationship is supervisor < boss
Here's how I did it:
SELECT t1.*,
t2.employee,
t2.email
FROM tab t1
LEFT JOIN tab t2
ON (t1.division = t2.division AND
t2.title = 'supervisor' AND
t1.title = 'employee')
OR (t2.title = 'boss' AND
t1.title = 'supervisor')
You'll find an SQL fiddle here.
If you want to update the current table (if columns are available), you can do the following (more or less the same as #lemon) :
UPDATE testing t1 JOIN testing t2 ON t2.`division`=t1.division OR t2.division="o" SET
t1.supervisor_name=t2.`employee`, t1.supervisor_email=t2.email
WHERE (CASE
WHEN t1.`title`="employee" THEN t2.title="supervisor"
WHEN t1.`title`="supervisor" THEN t2.title="boss"
END);
SELECT * FROM testing;

SQL Complex Filter/Join Issue

I'm a novice at SQL and I think this is a relatively basic query but I can't seem to get it to work.
I have two tables. One has group membership and the other details about the group. The key field between the two is Group.
Membership looks like this.
Person EffectiveDate Group
Mary 8/10/2017 A
Joe 8/05/2017 A
Peter 9/01/2017 B
Mike 9/2/2017 B
Alice 9/2/2017 B
Joe 9/10/2017 B
Pam 9/3/2017 C
Note that there are two entries for Joe because he changed groups.
GroupInformation Looks like this:
Group FullName Location Color
A Panthers New York Blue
B Steelers London Orange
C Archers Moscow Yellow
I want to run a query that, on any given day, will give me the individual's group membership along with team details.
So, I want to find the line with the MAX(EffectiveDate) in Membership for each individual person on the date run and left join the GroupInformation table on key Group
If I ran the query on 9/4 I'd get this:
Person EffectiveDate Group FullName Location Color
Mary 8/10/2017 A Panthers New York Blue
Joe 8/05/2017 A Panthers New York Blue
Peter 9/01/2017 B Steelers London Orange
Mike 9/2/2017 B Steelers London Orange
Alice 9/2/2017 B Steelers London Orange
Pam 9/3/2017 C Archers Moscow Yellow
If I ran the query on 9/13 I'd get this:
Person EffectiveDate Group FullName Location Color
Mary 8/10/2017 A Panthers New York Blue
Peter 9/01/2017 B Steelers London Orange
Mike 9/2/2017 B Steelers London Orange
Alice 9/2/2017 B Steelers London Orange
Joe 9/10/2017 B Steelers London Orange
Pam 9/3/2017 C Archers Moscow Yellow
Note that the difference between the two query results is Joe. The 9/4 run has him in Group A joining on 8/5 where the 9/13 run has him in Group B which he joined on 9/10.
My query code is as follow:
Select s.Person,
s.Group,
s.EffectiveDate,
g.FullName,
g.Location,
g.Color
From Membership s
Join GroupInformation g
on s.Group = g.Group
and s.EffectiveDate = (
Select Max(s1.EffectiveDate)
From Membership s1
where s1.Group = g.Group
and s1.EffectiveDate <= '2017-09-14')
However when I run this code I find in my actual data that it omits records. So if I have 150 records in membership the resulting query join and subquery operations will result in an answer with maybe 80 records.
Can't figure out what I'm doing wrong. Guidance please.
Thanks.
You are on the right track, but using the wrong correlation clause:
Select s.Person, s.Group, s.EffectiveDate, g.FullName, g.Location, g.Color
From Membership s Join
GroupInformation g
on s.Group = g.Group
WHERE s.EffectiveDate = (Select Max(s1.EffectiveDate)
From Membership s1
where s1.Person = s.Person and
s1.EffectiveDate <= '2017-09-14'
);
Note that group is a very poor name for a column name in SQL, because it is a SQL key word.
What you need is to recharacterize the membership data to group member names as well as dates, then use it as a subquery and join to it in this vein. You're basically saying "give me the max membership date of each person prior to a given date of interest." Caveat: if the EffectiveDate field is strictly 'Date' (rather than a DateTime), it could theoretically still fail if someone changed memberships twice on the same day (no date resolution beyond the day).
Suggest this as a possible alternative (warning this is very hastily thrown together and not tested):
select s.person, s.group, s.EffectiveDate, g.FullName,g.location, g.color
from (select m.person,m.group, max(m.effectivedate) effectivedate
from Membership m
where m.EffectiveDate <= '2017-09-14'
group by m.person,m.group) s
join GroupInformation g
on s.group=g.group

SQL exclude duplicated pairs of columns from a two-column select

I don't really know how to describe my problem and I haven't found an answer.
I have two tables, rating and reviewer. I want to get for every pair of reviewers their names if they rated the same movie.
I have this SQL query:
SELECT DISTINCT re1.name, re2.name
FROM reviewer re1, reviewer re2, rating ra1, rating ra2
WHERE re1.rid=ra1.rid AND re2.rid=ra2.rid AND ra1.mid=ra2.mid AND re1.rid!=re2.rid;
This is the tables structure: rating (rid, mid, stars, ratingdate), reviewer(rid, name)
This is what I want to get:
NAME NAME
Daniel Lewis Elizabeth Thomas
Elizabeth Thomas James Cameron
Ashley White Chris Jackson
Mike Anderson Sarah Martinez
Brittany Harris Chris Jackson
This is what I get:
NAME NAME
------------------------------ ------------------------------
Daniel Lewis Elizabeth Thomas
Elizabeth Thomas James Cameron
Chris Jackson Brittany Harris
Chris Jackson Ashley White
Ashley White Chris Jackson
James Cameron Elizabeth Thomas
Mike Anderson Sarah Martinez
Sarah Martinez Mike Anderson
Elizabeth Thomas Daniel Lewis
Brittany Harris Chris Jackson
How do I remove the duplicate rows where the name1 and name2 have already been selected as name2, name1 ?
I hope I was clear enough. Thanks.
Its a very subtle change (> vs your !=), but what you want to do is use a diagonal elimination approach, whereby you exclude any reviewer with a rid lower than the current one:
SELECT DISTINCT re1.name, re2.name
FROM reviewer re1
INNER JOIN rating ra1
ON re1.rid=ra1.rid
CROSS JOIN
reviewer re2
INNER JOIN rating ra2
ON re2.rid=ra2.rid
WHERE ra1.mid=ra2.mid AND re1.rid > re2.rid;
This way, you don't 'double count' pairs of reviewers which already have a match on the opposite / symmetric side of the diagonal.
I've also taken the liberty of moving the JOIN conditions into JOINs, rather than in the WHERE clause.
SqlFiddle here
This query selects all reviewers of each movie and pairs them up with all other reviewers (whether or not they have reviewed the same movie). It then uses an exists to only keep reviewers that have reviewed the same movie.
select re1.name, re2.name
from reviewer re1 join reviewer re2 on re2.rid < re1.rid
join rating ra1 on ra1.rid = re1.rid
where exists (
select 1 from rating ra2
where ra2.mid = ra1.mid
and ra2.rid = re2.rid
)

Is it joins again in ORACLE

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