SQL table select - sql

I have two tables:
Patients where I have patient_ID as primary key and other details.
Patients_Treatments where I have patient_ID from Patients as foreign key, treatment_code, and other columns.
I am requested to find all the patient's treatment codes that have the same treatment_code as patient whose id is 999.
I'm sitting for two days trying to find a solution and I just can't manage to think of something. It seems simple but I just can't find a solution.
Example:
The expected output are the details (Details means first name, last name, and patient ID) of: Tal Shalom Dan Shabtay Elad Gigi

If you are looking for the Treatment_Code and Patient information for the patients that share a Treatment_Code belonging to Patient_Id: 999, this should get you those results:
Select T.Treatment_Code, P.First_Name, P.Last_Name, P.Patient_Id
From Patients_Treatments T
Join Patients P On P.Patient_Id = T.Patient_Id
Where T.Patient_Id In
(
Select T1.Patient_Id
From Patients_Treatments T
Join Patients_Treatments T1 On T1.Treatment_Code = T.Treatment_Code
And T1.Patient_ID <> T.Patient_Id
Where T.Patient_Id = 999
)

Related

SQL Subquery or Join?

Desired result is to have all patients that have more than 1 allergy displayed with their PatientId (From Patient table, NOT Allergy table) and PatientName
2 Tables:
Patient table contains PatientId (Represented as P_), PatientName.
Allergy table contains PatientId (Represented as p_), AllergyName.
So far, I have 2 queries that I want to connect together but dont know how:
SELECT PatientId, PatientName
FROM Patient;
SELECT COUNT(AllergyName)
FROM Allergy
GROUP BY AllergyName
HAVING COUNT(AllergyName) >1;
I want to complete a calculation in the "background" without it being shown in the table. PatientId's are the same, just that for Patient table it is an uppercase P and lowercase p for Allergy table.
SELECT PatientId, PatientName
FROM Patient INNER JOIN (SELECT COUNT(*) as allergy_count, PatientId
FROM Allergy
GROUP BY PatientId
HAVING COUNT(*) >1) aggr ON Patient.PatientId=aggr.PatientId
I assume this is what you are asking for:
SELECT Patient.PatientId, Patient.PatientName
FROM Patient
INNER JOIN Allergy ON Patient.PatientId = Allergy.patientId
GROUP BY Allergy.patientId
HAVING COUNT(Allergy.AllergyName)>1;
EDIT:
all patients that have more than 1 allergy displayed with their
PatientId (From Patient table, NOT Allergy table) and PatientName
I guess from that you don't need to display the count.
Below code should solve the purpose for you:
SELECT P.PatientID, P.PatientName from Patient P
JOIN Allergy A ON A.PatientID = P.PatientID
GROUP BY A.AllergyName
HAVING COUNT(A.PatiendID) > 1
Inner queries can cost you performance degrade in case of large datasets so joins are recommended to optimise query performance.
This should work.
SELECT PatientId, PatientName from (
SELECT PatientId, PatientName, (SELECT COUNT(AllergyName)
FROM Allergy A
WHERE A.PatientId= P.PatientId
GROUP BY patientID
HAVING COUNT(AllergyName) >1)
FROM Patient P)
Assuming you require only patient id and name the below query is suitable for your requirement.

SQL getting the average count of diagnosis based on specialty

I have 2 tables one for appointments and one for doctors.
I want to select the average number of patients for each specialty, which is stored in the doctors table. The appointments table has the patients' id the doctors' id and the diagnosis, if a patient has had a diagnosis.
I tried this, but doesn't work.
SELECT AVG(patientAMKA)
FROM appointments
WHERE diagnosis IS NOT NULL
GROUP
BY doctor.specialty
EDIT: I just want to clarify that patientAMKA is the id of the patient.
EDIT2: I specifically mean how many patients (with a diagnosis) exist for each speciaity, then take the average of those numbers.
Sounds like it would be something like:
SELECT d.specialty, COUNT(*)
FROM doctor d
INNER JOIN appointments a ON d.id = a.doctor_id
WHERE diagnosis IS NOT NULL
GROUP BY d.specialty
SELECT doc.specialty, AVG(app.patientAMKA)
FROM doctor doc
JOIN appointments app ON doc.doctorid = app.doctorid
WHERE app.diagnosis IS NOT NULL
GROUP BY doc.specialty
Based on your clarifications, I believe what you want is:
SELECT
AVG(CountOfDiagnoses) as TheAverage
FROM
(
SELECT
d.specialty,
COUNT(1) as CountOfDiagnoses
FROM
appointments a
JOIN doctor d ON
d.doctor_id = a.doctor_id
WHERE
a.diagnosis IS NOT NULL
GROUP BY
d.specialty
) Counts

Assistance with SQL query

Suppose we have 2 tables :
Patients (ID, name)
Patients_Treatments (PatientID, treatment_code)
I would like the query to retrieve all the patients who received at least all the treatments of patient with id='999999999'
I've tried many combinations and nothing worked, all I've got is patients who got at least one of '9999999999' treatments.
One method uses a self join and comparison in the having clause:
select pt2.patientId
from patient_treatments pt join
patient_treatments pt2
on pt.treatment_code = pt2.treatment_code and pt.patientid <> pt2.patientid
where pt.id = '999999999'
group by pt2.patientId
having count(pt2.treatment_code) = (select count(*) from patient_treatments pt where pt.id = '999999999');
Note: this version assumes that there are no duplicates in Patient_Treatments.
If you have duplicates in the data, you can use count(distinct):
having count(distinct pt2.treatment_code) = (select count(distinct pt.treatment_code) from patient_treatments pt where pt.id = '999999999');
The idea is
(1) Select treatment codes belonging to patient "999999999"
(2) Select only treatment records whose treatment code matches one of the treatment codes belonging to patient "999999999"
(3) Group these by patient_id
(4) Use a HAVING statement and COUNT (DISTINCT) to select only those Patient ID's which have the same number of different treatment codes as patient "999999999".
select pt.Patient_ID,count(distinct pt.treatment_code)
from
Patient_treatments pt
inner join
(select distinct treatment_code
from
Patient_treatments pt
where pt.Patient_ID="999999999"
)t1
on t1.treatment_code=pt.treatment_code
where pt.Patient_ID<>"999999999"
group by pt.Patient_ID
having count(distinct pt.treatment_code)=
(select count(distinct treatment_code)
from
Patient_treatments pt
where pt.Patient_ID="999999999"
);
With the following schema, only patient 1 is selected:-
Create table Patient_Treatments
(
Patient_ID varchar(10),
Treatment_code varchar(10)
);
Insert into Patient_Treatments
values
("1","abc"),
("1","def"),
("1","def"),
("1","ghi"),
("2","abc"),
("2","def"),
("2","def"),
("3","ghi"),
("999999999","abc"),
("999999999","def"),
("999999999","ghi"),
("999999999","ghi")
http://sqlfiddle.com/#!9/03a84b

SQL display data according to criteria

A) I have a table of doctors. Each doctor has a unique username, as well as a rating and a specialty. There is a also a table of Surgeries. It contains (among other things)
an attribute with doctor's unique username. It is not unique.
I'm trying to create a table that displays for each specialty. the data:
Speciality | Avg. Rating for Each Speciality | # of surgeries performed by Speciality
(first column is just the name of the specialty)
My best so far:
SELECT D.Speciality,t1.Avg, t0.CPT FROM DOCTOR as D
INNER JOIN(
SELECT AVG(AvgRating) as Avg, Speciality
FROM Doctors as D1
GROUP BY D1.Speciality
) as t1 ON D.Speciality=t1.Speciality
INNER JOIN(
SELECT COUNT(CPT) as CPT, Speciality
FROM PERFORM_SURGERY AS P
GROUP BY P.Speciality
)t0 ON t0.SPECIALITY=D.SPECIALITY
;
B) The doctor table includes a unique username and a non-unique name. There is also a Prescription table. It contains the both the doctor's username and patient's username.
Now there are 3 more tables that we need. One is a Req_surgery, Surgery and Visit.
Req_surgery contains the Doctor's username and a CPT (CPT is unique). The Surgery table has a primary key of CPT, and it also contains the cost of the surgery. Visit contains the doctor's username and patient's username as well as the cost of the visit.
I want a table with:
Doctor Name | No of Patients Seen | No of Prescriptions written | Total Billing
that lists each Doctor's name and the required info.
So far I have:
SELECT t1.name, t3.Visits, t2.Prescriptions, t4.money
FROM DOCTOR as D
INNER JOIN(
SELECT (FName + LName) as name, Username
FROM DOCTOR
) t1 ON t1.userName=D.username
INNER JOIN(
SELECT DUsername, COUNT(DateVisit) AS Prescriptions
FROM PRESCRIPTION
WHERE MONTH(DateVisit) = $month
AND YEAR(DateVisit)=$year
)t2 ON D.Username = t2.DUsername
INNER JOIN(
SELECT COUNT(DATEVISIT) as Visits, DUsername
FROM VISIT as V
WHERE MONTH(DateVisit) = $month
AND YEAR(DateVisit)=$year
)t3 ON D.Username=t3=DUsername
I didn't even finish because (a) I know what I have is wrong and I don't know how to fix it, and (b) I don't see how to compute the revenue for each doctor.
Doctor has primary key of Username.
Surgeries has primary key of CPT.
Req_Surgery has foreign key of the Doctor's Username (henceforth DU) that references Doctor(Username).
SELECT (FName + LName) as name, t3.Visits, t2.Prescriptions, t4.money
FROM DOCTOR as D
INNER JOIN(
SELECT DUsername, COUNT(DateVisit) AS Prescriptions
FROM PRESCRIPTION
WHERE MONTH(DateVisit) = $month
AND YEAR(DateVisit)=$year
GROUP BY DUsername
)t2 ON D.Username = t2.DUsername
INNER JOIN(
SELECT COUNT(DATEVISIT) as Visits, DUsername
FROM VISIT as V
WHERE MONTH(DateVisit) = $month
AND YEAR(DateVisit)=$year
GROUP BY DUsername
)t3 ON D.Username=t3.DUsername
I added grouping by DUsername to get the numbers for each doctor. Also I removed the t1 because in fact it's the same as D

Cross records between tables

I have this query:
select pa.id,pa.name
from patients pa
where (select count(distinct co.doctorID)
from consults co
where co.patientID=pa.id) = (select count(do.id)
from doctors do);
In which I select the patients who had consults with all the doctors.
I am counting the number of distinct doctors and see if is equal to the total of doctors.
But how can I do this with an exists and/or in without using count
You can use a nested NOT EXISTS:
select pa.id,pa.name
from patients pa
where NOT EXISTS
(
select 1 FROM doctors do
where NOT EXISTS
(
SELECT 1 FROM consults co
WHERE co.doctorID=do.id
AND pa.id=co.patientID
)
)
In other words, select all patients without a doctor that was not consulted. At least it should give you the idea.
I think you can try even better solution with NOT EXISTS that will not require counts at all:
SELCT pa.id,pa.name
FROM patients pa
WHERE NOT EXISTS (SELECT *
FROM doctors do
LEFT JOIN consults co
ON co.doctorID ON do.id
WHERE co.patientID=pa.id
AND co.doctorID IS NULL
)
In sub-query we get all the doctors and see whether all of them have consult for current patient. If co.doctorID IS NULL, that doctor was not visited by patient.