Inner Join of three different Tables - sql

I am working in Oracle APEX. I want to make a report from three different tables (Patient, History, Treatment) through INNER JOIN . Tables are as fallows.
PATIENT (Par_Id(Pk),Pat_Name,Pat_Gender)
HISTORY (His_Id(Pk),Pat_id(Fk),Treated_By)
and
Treatment (
Treat_Id,
His_id(Fk),Pat_id(Fk)
,Treat_Type
,Charges)
How I am going to display all the mentioned columns of the three Tables in
the report.
Thanks.

You should always specify the columns to return, especially as the tables contain identical column names
SELECT p.Par_Id, p.Pat_Name, p.Pat_Gender,
h.His_Id, h.Treated_By,
t.Treat_Id, t.Treat_Type, t.Charges
FROM Patient p
INNER JOIN History h
ON p.PAR_ID = h.PAT_ID
INNER JOIN Treatment t
ON h.HIS_ID = t.HIS_ID AND p.PAR_ID = h.PAT_ID

This should do the trick
SELECT * FROM Patient p
INNER JOIN History h
ON p.PAR_ID = h.PAT_ID
INNER JOIN Treatment t
ON h.HIS_ID = t.HIS_ID AND p.PAR_ID = h.PAT_ID

Try this
Select * from
PATIENT inner join HISTORY on par_id=HISTORY.Pat_id
inner join Treatment on par_id=Treatment.Pat_id

It is too simple in mysql
SELECT
*
FROM PATIENT as p
LEFT JOIN HISTORY as h ON h.Pat_id = p.Pat_Id
LEFT JOIN Treatment as t ON t.His_id = h.His_Id

Related

Joining 3 tables in sql-server

I have three tables in sql-server like table A table B table C.
How can I join 3 tables as expressed in the image below?
More information needed to give you a correct piece of code, but from the image you need LEFT JOINs.
(ID's have been presumed)
SELECT *
FROM Customers c
LEFT JOIN Items i ON c.iid = i.id
LEFT JOIN Sales s ON c.sid = s.id
It's never too late :)
Most probably you'll need this:
select ...
from customers
full outer join (items inner join sales on (xxx)) on (xxx)

SQL include entries with no data

Here is my sql statement in Oracle that I am working with:
SELECT FACILITY.fac_name
, SUM(FEE_LOG.fee_amount) AS TOTAL_FEES
FROM FACILITY
, BOOK_DETAIL
, TRANS_LOG
, FEE_LOG
, TRANS_TYPE
WHERE
FACILITY.fac_id = BOOK_DETAIL.fac_id
AND BOOK_DETAIL.bkdt_id = TRANS_LOG.bkdt_id
AND TRANS_LOG.trans_id = FEE_LOG.trans_id
AND TRANS_LOG.trans_type_id = TRANS_TYPE.trans_type_id
AND
(
TRANS_TYPE.trans_type_desc = 'LOST'
OR TRANS_TYPE.trans_type_desc = 'CHECKIN'
)
GROUP BY FACILITY.fac_name;
It outputs something similar to this:
FACILITY TOTAL_FEES
Facility 1 8.45
Facility 2 4.23
Facility 3 5.23
I have 2 other facilities but they do not have any fees associated with them. I want to show them as 0
So the output would be like:
FACILITY TOTAL_FEES
Facility 1 8.45
Facility 2 4.23
Facility 3 5.23
Facility 4 0
Facility 5 0
ER Diagram
Use LEFT JOIN instead of implicit INNER JOIN for the FEE_LOG table
SELECT FACILITY.fac_name
, SUM(FEE_LOG.fee_amount) AS TOTAL_FEES
FROM FACILITY
JOIN BOOK_DETAIL ON FACILITY.fac_id = BOOK_DETAIL.fac_id
JOIN TRANS_LOG ON BOOK_DETAIL.bkdt_id = TRANS_LOG.bkdt_id
LEFT JOIN FEE_LOG ON TRANS_LOG.trans_id = FEE_LOG.trans_id
JOIN TRANS_TYPE TRANS_LOG.trans_type_id = TRANS_TYPE.trans_type_id
WHERE TRANS_TYPE.trans_type_desc IN ('LOST', 'CHECKIN')
GROUP BY FACILITY.fac_name;
Use outer joins and the on clause:
SELECT FACILITY.fac_name, SUM(nvl(FEE_LOG.fee_amount,0)) AS TOTAL_FEES
FROM FACILITY
left join BOOK_DETAIL
on FACILITY.fac_id = BOOK_DETAIL.fac_id
left join TRANS_LOG
on BOOK_DETAIL.bkdt_id = TRANS_LOG.bkdt_id
left join FEE_LOG
on TRANS_LOG.trans_id = FEE_LOG.trans_id
left join TRANS_TYPE
on TRANS_LOG.trans_type_id = TRANS_TYPE.trans_type_id
and TRANS_TYPE.trans_type_desc in ('LOST', 'CHECKIN')
GROUP BY FACILITY.fac_name;
Note: If these facilities you are referring to, that do not have any fees, have rows on BOOK_DETAIL or TRANS_LOG you can replace the outer join with an inner join (for just those tables). Any table at which point there may or may not be a related record you have to use an outer join.
Try this:
SELECT f.fac_name
, coalesce(SUM(fl.fee_amount),0) AS TOTAL_FEES
FROM FACILITY AS f
INNER JOIN BOOK_DETAIL AS bd
ON bd.fac_id = f.fac_id
INNER JOIN TRANS_LOG AS tl
ON tl.bkdt_id = bd.bkdt_id
LEFT OUTER JOIN FEE_LOG AS fl
ON fl.trans_id = tl.trans_id
INNER JOIN TRANS_TYPE AS tt
ON tt.trans_type_id = tl.trans_type_id
WHERE tt.trans_type_desc in ('LOST' , 'CHECKIN')
GROUP BY f.fac_name;
NB: when you list tables after from with commas between them you're effectively using a cross join.
When you add a condition to your where statement matching a field from one table to a field from another, the join becomes an inner join.
To select all records from one table along with any matches which may or may not exist from another you need an outer join.
There are 3 types:
left outer join where you want all records from the first table listed and any matching records from the second.
right outer join for all records from the second with only matches from the first.
full outer join is all records from both tables, alongside one another where there's a match.
You should always specify the type of join rather than implying it through where clauses / commas, as this makes your intentions clearer and thus your code more readable.

Complex SQL Code

I am having trouble with a SQL query that corresponds to multiple different tables. I have written the following code, but it seems to combine every single booking with every invoice rather than finding the specific invoice that matches a specific booking. Any help would be greatly appreciated.
$sql = "SELECT INVOICE.invoice_id,
g.guest_first_name,
g.guest_last_name,
g.booking_num_guests,
g.booking_num_nights,
CURRENCY.currency_name,
INVOICE.invoice_nightly_rate,
INVOICE.invoice_deposit_amount,
INVOICE.invoice_paid,
ACCOUNT.account_name
FROM INVOICE
INNER JOIN BOOKING
ON INVOICE.invoice_booking_id = BOOKING.booking_id
INNER JOIN CURRENCY
ON INVOICE.invoice_currency_id = CURRENCY.currency_id
INNER JOIN ACCOUNT
ON INVOICE.invoice_account_id = ACCOUNT.account_id
INNER JOIN (
SELECT GUEST.guest_first_name,
GUEST.guest_last_name,
BOOKING.booking_num_guests,
BOOKING.booking_num_nights
FROM BOOKING
INNER JOIN GUEST
ON BOOKING.booking_guest_id = GUEST.guest_id) g
ON INVOICE.invoice_booking_id = BOOKING.booking_id";
Since you already joined INVOICE and BOOKING table in the first inner join, the last inner join should be between BOOKING and GUEST table. Change your query to below
$sql = "SELECT
INVOICE.invoice_id,
GUEST.guest_first_name,
GUEST.guest_last_name,
BOOKING.booking_num_guests,
BOOKING.booking_num_nights,
CURRENCY.currency_name,
INVOICE.invoice_nightly_rate,
INVOICE.invoice_deposit_amount,
INVOICE.invoice_paid,
ACCOUNT.account_name
FROM INVOICE
INNER JOIN BOOKING
ON INVOICE.invoice_booking_id = BOOKING.booking_id
INNER JOIN CURRENCY
ON INVOICE.invoice_currency_id = CURRENCY.currency_id
INNER JOIN ACCOUNT
ON INVOICE.invoice_account_id = ACCOUNT.account_id
INNER JOIN GUEST
ON BOOKING.booking_guest_id = GUEST.guest_id";

JOIN Across 3 tables

I am trying to join together 3 tables and potentially retrieve data from any of the columns.
I have a product and a lifestyle and a 'mapping table' that essentially contains references between the 2.
I want to do it properly using joins - but it is proving troublesome. If i use 'WHEREs' it works.
Here it is
This returns more results than I expect - it is probably doing the right thing, just not what I want!
SELECT DISTINCT PROFDESC.*
FROM PROFDESC
INNER JOIN PRODUCT ON PRODFUND.PRODCD = PRODUCT.PRODCD
INNER JOIN PRODFUND ON PRODFUND.PDFDCODE = PROFDESC.PROFREF
WHERE PRODFUND.PDFDTYPE = 2
This works fine but doesn't 'join' the tables.
SELECT DISTINCT PROFDESC.*
FROM PROFDESC, Product, Prodfund
WHERE
PRODFUND.PRODCD = PRODUCT.PRODCD and
PRODFUND.PDFDCODE = PROFDESC.PROFREF
AND PRODFUND.PDFDTYPE = 2;
I believe my first one is literally joining A to B and B to C where as I want the connection to include A to C
any suggestions?
You just need to have the tables in the query previously defined. This should work fine.
SELECT DISTINCT PROFDESC.*
FROM PROFDESC
INNER JOIN PRODFUND ON PRODFUND.PDFDCODE = PROFDESC.PROFREF
INNER JOIN PRODUCT ON PRODFUND.PRODCD = PRODUCT.PRODCD
WHERE PRODFUND.PDFDTYPE = 2
You should use the correct order when joining
SELECT DISTINCT PROFDESC.*
FROM
PROFDESC
INNER JOIN PRODFUND
ON PROFDESC.PROFREF = PRODFUND.PDFDCODE
INNER JOIN PRODUCT
ON PRODFUND.PRODCD = PRODUCT.PRODCD
WHERE
PRODFUND.PDFDTYPE = 2
But why are you joining to PRODUCT? You are not referring to any columns of it. Does the join somehow narrow the result? If not, drop it:
SELECT DISTINCT PROFDESC.*
FROM
PROFDESC
INNER JOIN PRODFUND
ON PROFDESC.PROFREF = PRODFUND.PDFDCODE
WHERE
PRODFUND.PDFDTYPE = 2
Maybe the DISTINCT can be dropped then (depending on the cardinality of the join).

Joining multiple tables and getting multiple attributes from one of them

I'm trying to join multiple tables together for building a report. The report lists a course, revisions made to it, and who requested, made and approved the revisions.
Under requested, made an approved, the values are employee numbers. I'm trying to join my innerjoined table above, with the Employee table so I can list the names (not just employee numbers) of those that requested, made and approved revisions.
This is what I have which I know is totally wrong.
SELECT *
FROM Courses
INNER JOIN CourseRevisions ON CourseRevisions.PELID = Courses.PELID
INNER JOIN CourseGroups ON CourseGroups.CourseGroupID = Courses.CourseGroupID
INNER JOIN [dbo].[OPG_Employees] ON OPG_Employees.EmployeeID = CourseRevisions.UpdatedBy
AND OPG_Employees.EmployeeID = CourseRevisions.ApprovedBy
AND OPG_Employees.EmployeeID = CourseRevisions.RequestedBy
This only returns a single result which just happens to have the same employee ID listed for all 3 (Requested, Approved and Updated)
How would i get it so I can get the table result for individual employees in each?
You have to join to the OPG_Employees table once for each field, i.e. 3 times in the example above. One INNER JOIN to it for UpdatedBy, one INNER JOIN for ApprovedBy, one INNER JOIN for RequestedBy.
Something like so:
SELECT *
FROM Courses
INNER JOIN CourseRevisions ON CourseRevisions.PELID = Courses.PELID
INNER JOIN CourseGroups ON CourseGroups.CourseGroupID = Courses.CourseGroupID
INNER JOIN [dbo].[OPG_Employees] empUpdatedBy ON empUpdatedBy.EmployeeID = CourseRevisions.UpdatedBy
INNER JOIN [dbo].[OPG_Employees] empApprovedBy ON empApprovedBy.EmployeeID = CourseRevisions.ApprovedBy
INNER JOIN [dbo].[OPG_Employees] empRequestedBy ON empRequestedBy.EmployeeID = CourseRevisions.RequestedBy
You need a separate join for each employee being referenced:
SELECT *
FROM Courses INNER JOIN
CourseRevisions
ON CourseRevisions.PELID = Courses.PELID INNER JOIN
CourseGroups
ON CourseGroups.CourseGroupID = Courses.CourseGroupID INNER JOIN
[dbo].[OPG_Employees] UpdateEmp
ON UpdateEmp.EmployeeID = CourseRevisions.UpdatedBy INNER JOIN
[dbo].[OPG_Employees] ApprovedEmp
on OPG_ApprovedEmp.EmployeeID = CourseRevisions.ApprovedBy INNER JOIN
[dbo].[OPG_Employees] RequestedEmp
on RequestedEmp.EmployeeID = CourseRevisions.RequestedBy
Your original formulation required that all three ids be exactly the same.