Comparing values from two different tables in SQL Plus Oracle - oracle

I have multiple tables with some foreign keys in some. Here are the tables;
Doctor
Doctor_id, FirstName, SecondName,etc...
Hospital
Hospital_id, Name...
Job
Job_id
fk Doctor_id
fk Hospital_id
I'm trying to show a list of doctors that works in 'X' hospital. How would I run this query?
SELECT FirstName, SecondName
FROM Doctor, Job, Hospital
WHERE Hospital.Name = 'HospitalName' AND Job.hospital_id = Hospital.hospital_id;
I'm not sure if that particular query is right because it shows every single doctor (not the ones that work in 'HospitalName'. If that is correct than I guess the foreign keys ain't right?
Thanks in advance. DG

You should learn to use proper join syntax. Then mistakes like this are much less likely to occur:
SELECT d.FirstName, d.SecondName
FROM Doctor d join
Job j
on d.Doctor_id = j.Doctor_Id join
Hospital h
on j.hospital_id = h.hospital_id
WHERE h.Name = 'HospitalName';
This also adds in table aliases for every column, so someone reading the query knows where they are coming from.

You are missing one join condition.
SELECT FirstName, SecondName
FROM Doctor, Job, Hospital
WHERE Hospital.Name = 'HospitalName'
AND Job.hospital_id = Hospital.hospital_id
AND job.Doctor_id = Doctor.doctor_id;

Related

JOIN 4 tables in one (Oracle R11)

I need to create a query that shows the "Legal Entity", "Application Name", "Close Date" and "Period" I'm working with Oracle R11, Right now I've found the query for
"Legal Entity"
SELECT name
FROM hr_organization_information HOI
INNER JOIN hr_all_organization_units HAOU
ON HOI.ORGANIZATION_ID = Haou.Organization_Id
WHERE HOI.org_information_context LIKE 'Legal Entity Accounting'
ORDER BY NAME ASC;
and for "Application Name, Close Date, Period"
SELECT A.APPLICATION_ID,
B.APPLICATION_NAME,
TO_CHAR(A.END_DATE,'HH24:MI DD-MON-YYYYI'),
A.PERIOD_NUM
FROM GL_PERIOD_STATUSES A
INNER JOIN FND_APPLICATION_TL B ON A.APPLICATION_ID = B.APPLICATION_ID
WHERE A.Application_Id=101
AND LANGUAGE='US'
OR A.APPLICATION_ID=200
AND LANGUAGE='US'
OR A.APPLICATION_ID=222
AND LANGUAGE='US';
Separately but I haven't found the way to join them in one query, can you help me with that?
Antonio, I think Brian has given you sound advice. Posting to an EBS forum (or whatever application this is) might also be worthwhile if his advice has not lead you to the answer. I will offer that sometimes the way to join table_A and table_B is through table_C. That is, if you do not find any directly related data in the queries of one se to one of the tables in the other set then look at the FK defined on and pointing to these tables to see if you can find a table not currently part of either query that relates the sets. You figure out how to join each of your current queries to it and that is how you join the two queries together.
Thank you all!
The advices that all of you gave to me were useful, I've found the table HR_LEGAL_ENTITIES (Table C) that have two columns that allow me to join Table A with Table B, the final query was:
SELECT HAOU.NAME,
FAT.APPLICATION_NAME,
TO_CHAR(GPS.END_DATE,'HH24:MI DD-MON-YYYY'),
GPS.PERIOD_NUM
FROM HR_ALL_ORGANIZATION_UNITS HAOU
INNER JOIN HR_LEGAL_ENTITIES HLE
ON HLE.ORGANIZATION_ID = HAOU.ORGANIZATION_ID
INNER JOIN GL_PERIOD_STATUSES GPS
ON HLE.SET_OF_BOOKS_ID = GPS.SET_OF_BOOKS_ID
INNER JOIN FND_APPLICATION_TL FAT
ON GPS.APPLICATION_ID = FAT.APPLICATION_ID
WHERE GPS.Application_Id IN (101,200,222) AND LANGUAGE='US'
ORDER BY NAME ASC;
Regards!

Better solution than left join subqueries?

TablePatient.Patient_ID(PK)
TableProviders.Encounter (joins to PK)
TableProviders.Provider_Type
TableProviders.Provider_ID
TableNames.Full_Name
TableNames.Provider_ID (joins to Table Names)
I want a query that will give, for all the Patient_IDs, the Full_Name of the provider for every Provider ID.
There are about 30 provider_types.
I have made this already using a left join a ton of left joins. It takes a long time to run and I am thinking there is a trick I am missing.
Any help?
Ok, my previous answer didn't match at all what you meant. You want to pivot the table to have on each line one Patient_ID with every Full_name for every provider_type. I assume that each patient has only one provider for one type and not more ; if more, you will have more than one row for each patient, and anyway I don't think it's really possible.
Here is my solution with pivot. The first part is to make it more understandable, so I create a table named TABLE_PATIENT in a subquery.
WITH TABLE_PATIENT AS
(
SELECT TablePatient.Patient_ID,
TableProviders.Provider_Type,
TableNames.Full_Name
FROM TablePatient LEFT JOIN
TableProviders on TablePatient.Patient_ID = TableProviders.Encounter
LEFT JOIN
TableNames on TableNames.Provider_ID = TableProviders.Provider_ID
group by TablePatient.Patient_ID,
TableProviders.Provider_Type,
TableNames.Full_Name
)
SELECT *
FROM TABLE_PATIENT
PIVOT
(
min(Full_name)
for Provider_type in ([type1], [type2],[type3])
) AS PVT
So TABLE_PATIENT just has many rows for each patient, with one provider each row, and the pivot puts everything on a single row. Tell me if something doesn't work.
You need to write every type you want in the [type1],[type2] etc. Just put them inside [], no other character needed as ' or anything else.
If you put only some types, then the query will not show providers of other types.
Tell me if something doesn't work.
If I understand what you mean, you just want to group the answer by Patient Id and then Provider ID. A full name is unique on a provider id right ?
This should be something like
SELECT TablePatient.Patient_ID,
TableProviders.Provider_ID,
TableNames.Full_Name
FROM TablePatient LEFT JOIN
TableProviders on TablePatient.Patient_ID = TableProviders.Encounter
LEFT JOIN
TableNames on TableNames.Provider_ID = TablerProviders.Provider_ID
group by TablePatient.Patient_ID,
TableProviders.Provider_ID,
TableNames.Full_Name
You can either group by TableNames.Full_Name or select First(TableNames.Full_Name) for example if indeed a full name is unique to a provider ID.
Note : I used the SQL server Syntax, there can be différences with Oracle ..

Active Record Join with most recent association object attribute

I have a Contact model which has many Notes. On one page of my app, I show several attributes of a table of contacts (name, email, latest note created_at).
For the note column, I'm trying to write a joins statement that grabs all contacts along with just their latest note (or even just the created_at of it
What I've come up with is incorrect as it limits and orders the contacts, not their notes:
current_user.contacts.joins(:notes).limit(1).order('created_at DESC')
If you just want the created_at value for the most recent note for each contact, you can first create a query to find the max value and then join with that query:
max_times = Note.group(:contact_id).select("contact_id, MAX(created_at) AS note_created_at").to_sql
current_user.contacts.select("contacts.*, note_created_at").joins("LEFT JOIN (#{max_times}) max_times ON contacts.id = max_times.contact_id")
If you want to work with the Note object for the most recent notes, one option would be to select the notes and group them by the contact_id. Then you can read them out of the hash as you work with each Contact.
max_times = Note.group(:contact_id).select("contact_id, MAX(created_at) AS note_created_at").to_sql
max_notes = Note.select("DISTINCT ON (notes.contact_id) notes.*").joins("INNER JOIN (#{max_times}) max_times ON notes.contact_id = max_times.contact_id AND notes.created_at = note_created_at").where(contact_id: current_user.contact_ids)
max_notes.group_by(&:contact_id)
This uses DISTINCT ON to drop dups in case two notes have exactly the same contact_id and created_at values. If you aren't using PostgreSQL you'll need another way to deal with dups.

Oracle relational database, querying/joining multiple tables

I know most people here tend to frown on people asking homework questions on here, but I am really stumped on one question in my database systems class.
List all cities (city name and zip code where there is at least one property for rent managed by staff who works in the branch office at ‘1119 Leighton Ave’. Order your result by ascending order of city name. Otherwise, zero point.
The database schema is:
Branch (bNo, street, zipcode)
Staff (sNo, fName, lName, position, sex, dob, salary, bNo)
Property (pNo, street, zipcode, type, room, rent, oNo, sNo, bNo)
Owner (oNo, fName, fName, street, zipcode, phone)
Client (cNo, fName, lName, phone, prefType, maxRent)
Viewing (pNo, cNo, viewDate, cmmt)
Zip (city, state, zipcode)
And this is the query that I have tried to put together, very unsuccessfully...
SELECT z.city, p.zipcode
FROM Zip z, Property p
WHERE p.bNo = (SELECT bNo
FROM Branch
WHERE street = '1119 Leighton Ave');
I am having a bit of hard time with the joins. This statement above does NOT even come close to working right. I am digging through my book and the internet, trying to find some sort of help. Any help would be greatly appreciated. Thanks in advance.
UPDATE
I am currently trying:
SELECT DISTINCT Zip.city, Zip.zipcode AS Zip
FROM Zip
JOIN Property ON Zip.zipcode = Property.zipcode
JOIN Branch ON Zip.zipcode = Branch.zipcode
WHERE Property.bNo = (SELECT bNo
FROM Branch
WHERE Street = '1119 Leighton Ave')
ORDER BY Zip.city;
The output looks a lot better, but I don't think it is correct. I am checking it now.
UPDATE #2
Okay, so by running this query:
SELECT DISTINCT zipcode
FROM Property
WHERE bNo = 'B001';
and just as an FYI B001 is the branch number for the Branch located at 1119 Leighton Ave. Anyways, that command gave me the following zip codes:
36205
36251
36264
36206
36277
36272
36265
36203
36201
When I run the above command:
SELECT DISTINCT Zip.city, Zip.zipcode AS Zip
FROM Zip
JOIN Property ON Zip.zipcode = Property.zipcode
JOIN Branch ON Zip.zipcode = Branch.zipcode
WHERE Property.bNo = (SELECT bNo
FROM Branch
WHERE Street = '1119 Leighton Ave')
ORDER BY Zip.city;
This is my output:
City Zip
--------------------- -----
ANNISTON 36206
JACKSONVILLE 36265
So, I believe that something is a little off with this query. But you guys have given me a GREAT start, I will continue playing with it and I am confident that I can probably figure it out. Thanks a ton guys.
I think I got it figured out thanks to all the help from everyone.
SELECT DISTINCT Zip.city, Zip.zipcode AS Zip
FROM Zip
JOIN Property ON Zip.zipcode = Property.zipcode
JOIN Branch ON Zip.zipcode = Property.zipcode
JOIN Staff ON Staff.bNo = Branch.bNo
WHERE Property.bNo = (SELECT bNo FROM Branch WHERE Street = '1119 Leighton Ave')
ORDER BY Zip.city
There are multiple ways to write JOIN queries in Oracle. A more standard SQL way is to do something like this:
SELECT t1.colNameA, t1.colNameB, t2.colNameC
FROM t1
JOIN t1.pid = t2.fkid
WHERE
t1.colNameA='whatever'
With that in mind, you might try the following steps:
List out all the columns that you need:
SELECT Zip.city, Zip.zipcode
List out all the tables that you need, including the relationships
between them:
FROM Zip
JOIN Property ON Zip.zipcode=Property.zipcode
JOIN Branch ON Zip.zipCode=Branch.zipcode
JOIN etc
Add the WHERE criteria.
WHERE Branch.street='1119 LeightonAve'
AND etc
Add ORDER BY clause
ORDER BY Zip.city
This is not the complete answer, but hopefully helps get you in the right direction.
EDIT #2
After your edit, I would suggest you need to research the keyword "DISTINCT". Something like this might be more what you are looking for:
SELECT DISTINCT Zip.city, Zip.zipcode
Try this
SELECT z.city, p.zipcode
FROM Zip z
JOIN Property p ON z.zipcode = p.zipcode -- city name and zip code where there is at least one property for rent
JOIN Staff s ON p.sNo = p.sNo -- managed by staff
JOIN Branch b ON s.bNo = b.bNo AND b.street = '1119 Leighton Ave' -- who works in the branch office at ‘1119 Leighton Ave’
ORDER BY z.city
JOIN(INNER JOIN) makes sure both table participating has the same value in at least one row, otherwise no record is returned.

Getting latest record for each userid in rails 3.2

I have user with name, location, created_at as important fields in table.
I want to retrieve for each user the latest location,i.e, I want something like this:
username location created_at
abc New York 2012-08-18 16:18:57
xyz Mexico city 2012-08-18 16:18:57
abc Atlanta 2012-08-11 16:18:57
only input is UId(1,2) array of userids.please help me to accomplish this.I just want to know how to write query using active record query interface.
Generally, this should be a standard way to solve this kind of problems:
SELECT l1.user, l1.location
FROM locations l1
LEFT JOIN locations l2 ON l1.user = l2.user AND l2.created_at > l1.created_at
WHERE l2.id IS NULL
The idea is to join the table with itself, and find those rows which don't have any row with the same user and greater created_at.
Of course, you should have (user, created_at) index on your table.
Now you should see how would that be represented in AR interface.
When
u_id
is the array of user ids, then
u_id.map{|i| User.find(i).location}
should be an array of the users locations.
You can Use
User.where(:uid => [1,2,3]).maximum('location')
which will create something like
SELECT MAX(`users`.`location`) AS max_id FROM `users` WHERE `users`.`id` IN (1, 2,3)

Resources