SQL Subquery or Join? - sql

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.

Related

SQL Removing Duplicate rows

I've been trying to remove duplicates using HAVING count(*) > 1, group by, distinct and sub queries but can't get any of these to work..
SELECT UserID, BuildingNo
FROM Staff INNER JOIN TblBuildings ON Staff.StaffID =
TblBuildingsStaffID
GROUP BY TblStaff.User_Code, BuildingNo
What I get is..
StaffID1 | BuildingNo1
StaffID1 | BuildingNo2
StaffID2 | BuildingNo2
StaffID3 | BuildingNo1
StaffID3 | BuildingNo2
I'm trying to get it so it just displays staff with one building number (if they have two regardless of which it shows) like:
StaffID1 | BuildingNo1
StaffID2 | BuildingNo2
StaffID3 | BuildingNo1
It can't be too hard.. I've tried CTE's left joining the building to the staff table, these come up NULL for some reason when I try this
Any help would be great!
Don't group by BuildingNo, then you can use having to filter out the groups you want.
SELECT s.UserID, min(b.BuildingNo) as buildingno
FROM Staff s
JOIN TblBuildings ON s.StaffID = b.TblBuildingsStaffID
GROUP BY s.UserID
having count(distinct b.BuildingNo) = 1;
The min() aggregate is required because buildingno is not part of the group by clause. But as the having() clause only returns those with one building, it doesn't change anything.
If you want to display all staff members, and simply pick one (arbitrary) building, then simply leave out the having condition.
If you want to include staff members without a building you need a left join:
SELECT s.UserID, min(b.BuildingNo) as buildingno
FROM Staff s
LEFT JOIN TblBuildings b ON s.StaffID = t.TblBuildingsStaffID
GROUP BY t.UserID;
Use row partition keyword in your query to avoid duplicacy
WITH CTE AS( SELECT ROW_NUMBER() OVER(PARTITION BY UserID ORDER BY UserID ) AS 'Num',UserID, BuildingNo
FROM Staff INNER JOIN TblBuildings ON Staff.StaffID =
TblBuildingsStaffID
GROUP BY TblStaff.User_Code, BuildingNo)
SELECT * FROM CTE
WHERE Num =1
try this -
SELECT distinct UserID, BuildingNo
FROM Staff INNER JOIN TblBuildings ON Staff.StaffID =
TblBuildingsStaffID

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

SQL table select

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
)

How to get distinct and lastest record with inner join query

I have two table named: customers and bill. customer and bill have one to many relation.
Customer table contains record of customer mobileNo,bikeNo etc
Bill table contain record of customer bill with bikeNo(foreign key),billdate etc.
I have query for that:
SELECT customer.mobileNo, bill.iDate AS Expr1
FROM (customer INNER JOIN
bill ON customer.bikeNo = bill.bikeNo)
ORDER BY bill.iDate;
Now How i get distinct and latest billdate record and mobileNo with this query?
Use GROUP BY and MAX():
SELECT customer.mobileNo, MAX(bill.iDate) AS iDate
FROM (customer INNER JOIN
bill ON customer.bikeNo = bill.bikeNo)
GROUP BY customer.mobileNo
ORDER BY iDate

SQL query for finding row with same column values that was created most recently

If I have three columns in my MySQL table people, say id, name, created where name is a string and created is a timestamp.. what's the appropriate query for a scenario where I have 10 rows and each row has a record with a name. The names could have a unique id, but a similar name none the less. So you can have three Bob's, two Mary's, one Jack and 4 Phil's.
There is also a hobbies table with the columns id, hobby, person_id.
Basically I want a query that will do the following:
Return all of the people with zero hobbies, but only check by the latest distinct person created, if that makes sense. Meaning if there is a Bob person that was created yesterday, and one created today.. I only want to know if the Bob created today has zero hobbies. The one from yesterday is no longer relevant.
select pp.id
from people pp, (select name, max(created) from people group by name) p
where pp.name = p.name
and pp.created = p.created
and id not in ( select person_id from hobbies )
SELECT latest_person.* FROM (
SELECT p1.* FROM people p1
WHERE NOT EXISTS (
SELECT * FROM people p2
WHERE p1.name = p2.name AND p1.created < p2.created
)
) AS latest_person
LEFT OUTER JOIN hobbies h ON h.person_id = latest_person.id
WHERE h.id IS NULL;
Try This:
Select *
From people p
Where timeStamp =
(Select Max(timestamp)
From people
Where name = p.Name
And not exists
(Select * From hobbies
Where person_id = p.id))