简体   繁体   中英

SQL for many to one to many table

I have three tables in an Access database that I am using in java via ucanaccess.

Patients (PK Pt_ID)
Endoscopy (PK Endo_ID, FK Pt_ID)
Histology (PK Histol_ID, FK Pt_ID)

1 patient can have many endoscopies 1 patient can have many histologies Endoscopy and histology are not related

I want to retrieve all the Endoscopies and histologies for a single patients in a single SQL query. Although I can write select statements for two tables I don't know how to do this across the three tables. Is it something like this

Select *.Endoscopy,*.Histology from Patients INNER JOIN Endoscopy, Histology ON Patient.Pt_Id=Endoscopy.Pt_ID, Patient.Pt_Id=Histology.Pt_ID

I'm sure that's a mess though...

If you have multiple Endoscopy records or multiple Histology records for the same Patient then you will receive duplicate/repeated records in your SELECT. I do no think there is a way around that unless you use 2 SELECT statements instead of 1.


SELECT Endoscopy.*, Histology.*
FROM Patients 
INNER JOIN Endoscopy ON Patients.Pt_Id = Endoscopy.Pt_ID
INNER JOIN Histology ON Patients.Pt_Id = Histology.Pt_ID
  • To select all records on a table in the select its table name/table alias .*
  • INNER JOIN will only select records where there is a relationship, once one of these tables does not contain a Pt_ID where it is contained in any one of the other tables then no record will be displayed with that Pt_ID
  • To add additional tables continue to add additional join statements
  • You used Patients (with S) in one location and Patient (no S) in another, make sure you use the correct naming. I am guessing its Patients but maybe its Patient .

This statement does almost the same as the above but uses LEFT JOIN syntax so that you will always get records for both tables even if one of the two tables does not have a record for a patient.

SELECT Endoscopy.*, Histology.*
FROM Patients 
LEFT JOIN Endoscopy ON Patients.Pt_Id = Endoscopy.Pt_ID
LEFT JOIN Histology ON Patients.Pt_Id = Histology.Pt_ID
WHERE Histology.Histol_ID IS NOT NULL OR Endoscopy.Endo_ID IS NOT NULL

The added WHERE clause ensures that you do not get a record with all NULL values where there is a patient but no records in either of those tables.

What kind of SQL DB are you using?
I believe this works on most.

SELECT * FROM Patients, Endoscopy, Histology 
WHERE Patient.Pt_Id=Endoscopy.Pt_ID
AND Patient.Pt_Id=Histology.Pt_ID

Also, I belive you have these switched around *.Endoscopy,*.Histology If you need to use that it should be Endoscopy.*, Histology.*

You can use the following query to select both endoscopies and histologies :

SELECT p.Pt_ID
     , e.Endo_ID
     , h.Histol_ID
FROM Patients p
INNER JOIN Endoscopy e ON p.Pt_Id = e.Pt_ID
INNER JOIN Histology h ON p.Pt_Id = h.Pt_ID

But I'm not sure this is really what you want. You might need to map the tables Patients , Endoscopy and Histology into Java classes ? In this case, you can consider the Java Persistence API (JPA). It helps you to handle these tables in your java code. Here is a JPA Quick Guide .

First idea is to use inner join (with correct syntax) but this is wrong. inner join returns patients who have both procedure. Pure left join returns additionally patients who have none. So this is the solution:

SELECT Patients.Pt_PK, Endoscopy.*, Histology.*
FROM Patients 
LEFT JOIN Endoscopy ON Patients.Pt_Id = Endoscopy.Pt_ID
LEFT JOIN Histology ON Patients.Pt_Id = Histology.Pt_ID
--exclude patients who don't have any
where coalesce(Endoscopy.Endo_ID, Histology.Histol_ID) is not null

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM