SQL display data according to criteria - sql

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

Related

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

Selecting columns from different tables

I need to display two columns from my attendance table (MEMBER_ID & MEETING_ID) and one column from my meeting table and finally two columns from my member table which displays the names that match with MEETING_ID.
The attendance table has a composite key (MEMBER_ID*, MEETING_ID*)
The member table's primary key is MEMBER_ID
Meeting table's primary key is MEETING_ID
My attempt is not working, can someone please help?
SELECT MEMBER_ID, MEETING_ID, MEETING_NAME MEMBER_FIRSTNAME, MEMBER_LASTNAME
FROM ATTENDANCE, MEMBER, MEETING
WHERE MEETING.MEMBER_ID = MEETING.MEMBER_ID;
End result needs to be:
MEMBER_ID MEETING_ID MEETING_NAME FIRSTNAME LASTNAME
0001 MEET0004 SPORTS DAY JOHN SMITH
May be you need this.
SELECT A.MEMBER_ID, A.MEETING_ID, M2.MEETING_NAME, M1.MEMBER_FIRSTNAME, M1.MEMBER_LASTNAME
FROM ATTENDANCE A, MEMBER M1, MEETING M2
WHERE M1.MEMBER_ID = A.MEMBER_ID
AND A.MEETING_ID = M2.MEETING_ID;
SELECT
a.MEMBER_ID
,a.MEETING_ID
,mt.MEETING_NAME
,mb.MEMBER_FIRSTNAME
,mb.MEMBER_LASTNAME
FROM
ATTENDANCE a
INNER JOIN MEMBER mb
ON a.MEMBER_ID = mb.MEMBER_ID
INNER JOIN MEETING mt
ON a.MEETING_ID = mt.MEETING_ID
;
Use Explicit Join Syntax and then setup your relationships using the ON conditions and the keys between the tables. Note I also used table aliases to shorten typying.

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
)

SQL find records with duplicate email and date of birth

I'm trying to write a query to find any duplicate records in my database. I want to find all records (not the count) where the EmailAddress AND DateofBirth (both columns) already exist on another record.
Account tbl contains the EmailAddress.
User tbl contains the DateOfBirth
Join on AccountID
The following query selects records where the EmailAddress exists in another record OR the DateOfBirth exists in another record, but I'm unable to combine the two conditions. If I'm correct so far, the 'and' on line 7 acts more like an 'or' in my case..?
select a.AccountName, a.EmailAddress, u.DateOfBirth from Account as a
join [User] as u
on a.AccountID = u.AccountID
where a.EmailAddress in (
select EmailAddress from Account group by EmailAddress having count(*) > 1
)
and
DateOfBirth in(
select DateOfBirth from [User] group by DateOfBirth having count(*) > 1
)
order by u.DateOfBirth, a.EmailAddress
For example, this may produce 50 records. If I look through them, I find 5 records all with the matching EmailAddress, however only 4 of them have the same DateOfBirth. The 5th record is displaying due to another record in the database with the same DateOfBirth but different EmailAddress.
I'd like to find only those records who have both the matching email and dob.
Thanks as always, please ask if you require a further description.
Regards
Json
Using your approach, you can use exists:
select a.AccountName, a.EmailAddress, u.DateOfBirth
from Account as a join
[User] as u
on a.AccountID = u.AccountID
where exists (select EmailAddress
from Account a2 join
[User] u2
on a.AccountID = u.AccountID
where a2.EmailAddress = a.EmailAddress and
u2.DateOfBirth = u.DateOfBirth
group by EmailAddress
having count(*) > 1
)
order by u.DateOfBirth, a.EmailAddress;
A better way is to use window/analytic functions:
select AccountName, EmailAddress, DateOfBirth
from (select a.AccountName, a.EmailAddress, u.DateOfBirth,
count(*) over (partition by a.EmailAddress, u.DateOfBirth) as cnt
from Account as a join
[User] as u
on a.AccountID = u.AccountID
) ua
where cnt > 1
order by DateOfBirth, EmailAddress;
Join the two tables on the account id.
Group by email and date
Show only those entries which have count(*) > 1 (using the HAVING expression).
In MySQL (I have no MS SQL server available at the moment), this can be done with:
SELECT * FROM a JOIN b ON a.account = b.account
GROUP BY email, birth
HAVING count(*) > 1;
Where I used the following commands to setup the tables a and b:
create table a (
account int primary key auto_increment,
email text
);
create table b (
account int,
birth date,
constraint foreign key (account) references a (account)
);
insert into a (email) values ("email1"), ("email1"), ("email2"), ("email2");
insert into b values (1, "2000-01-01"), (2, "2000-01-01"), (3, "2000-01-01"), (4, "2000-01-02");

SQL joining three tables and selecting information

I have 3 tables
Doctor - Staff_ID, Name, Position.
Consists_Of - Staff_Id, Team_Code.
Team - Team_Code, Telephone_No, Staff_ID
The team table consists of the team leader for each team who is also a doctor,
I need to return a table that has team_code, staff_Id, name, position
I have got
SELECT DISTINCT Team.team_code, Doctor.staff_ID, name, position
FROM Doctor, Team LEFT OUTER JOIN consists_of
ON Team.Team_code = consists_of.Team_code
But this is giving every each member of stay the team code, t1 and then t2 and then t3 and so on.
Any ideas?
What you need is use JOIN. The repetition occurred because you didn't specify on what field should Doctor and Team be joined
SELECT Team.team_code, Doctor.staff_ID, name, position
FROM Doctor
LEFT OUTER JOIN consists_of
ON Doctor.Staff_Id=consists_of.Staff_Id
LEFT OUTER JOIN Team
ON Team.Team_code = consists_of.Team_code
But why do you have Staff_Id in Team table?