Trouble with Full Text Search query - sql

I'm having trouble with this full text search query I'm trying to run. I need to do a full text search on two tables. If any of the terms are in either table I need to return the records from the first table.
select R.* from Request R
inner join Patients P on R.PatientID = P.PatientID
inner join containstable(Request,(*),#keywords)AS KEY_TBL
ON R.RequestID = KEY_TBL.[Key]
full outer join
(select R.* from Request R
inner join Patients P on R.PatientID = P.PatientID
inner join containstable(Patients,(*),#keywords) AS KEY_TBL2
ON P.PatientID = KEY_TBL2.[Key]) as b on R.RequestID = b.RequestID

All I needed was a Union instead of a full outer join.
select R.* from Request R
inner join Patients P on R.PatientID = P.PatientID
inner join containstable(Request,(*),#keywords)AS KEY_TBL
ON R.RequestID = KEY_TBL.[Key]
UNION
select R.* from Request R
inner join Patients P on R.PatientID = P.PatientID
inner join containstable(Patients,(*),#keywords) AS KEY_TBL2
ON P.PatientID = KEY_TBL2.[Key]

Related

SQL join subquery where condition

How can I effectively subquery a LEFT OUTER JOIN so that only rows that meet a specific condition in the join are included?
I'd like to only count PPPD's where converted_at IS NULL. However when I add PPPD.converted_at IS NULL, then the result is more limited than I'd like it to be because it only includes patient_profiles that do have a row with null in converted_at. Instead I'd like a count of all PPPD records that have converted_at = null
SELECT P.id, P.gender, P.dob,
count(distinct recommendations.id) AS recommendation_count,
count(distinct PPPD.id) AS community_submissions,
FROM patient_profiles AS P
LEFT OUTER JOIN recommendations ON recommendations.patient_profile_id = P.id
LEFT OUTER JOIN patient_profile_potential_doctors AS PPPD ON PPPD.patient_profile_id = P.id
WHERE P.is_test = FALSE
GROUP BY P.id
You need to add the condition in the ON clause:
SELECT P.id, P.gender, P.dob,
count(distinct r.id) AS recommendation_count,
count(distinct PPPD.id) AS community_submissions,
FROM patient_profiles P LEFT OUTER JOIN
recommendations r
ON r.patient_profile_id = P.id LEFT OUTER JOIN
patient_profile_potential_doctors PPPD
ON PPPD.patient_profile_id = P.id AND PPPD.converted_at IS NULL
WHERE P.is_test = FALSE;
GROUP BY P.id

Join 4 tables with inner join

I'm trying to write below query with INNER JOIN instead of AND
select ph.name, ph.position, d.name, COUNT(app.appointmentId)
from physician ph, works_in w, appointment app, department d
where ph.eid = w.physician
and d.did = w.department
and ph.eid = app.physician
group by ph.eid, ph.name, ph.position, d.name
.
I tried in this way, But It gets so many errors
select ph.name, ph.position, d.name, COUNT(app.appointmentId)
from physician ph inner join works_in w
on ph.eid = w.department,
department d inner join works_in w
on d.eid = w.department,
physician ph inner join appointment app
on ph.ph.eid = app.physician
group by ph.eid, ph.name, ph.position, d.name
How can I write it correctly with inner joins.
First let me reffer you to this site that explain all about join syntax's
Change your query to this:
select ph.name, ph.position, d.name, COUNT(app.appointmentId)
from physician ph
inner join works_in w
on ph.eid = w.department
inner join department d
on d.eid = w.department
inner join appointment app
on ph.ph.eid = app.physician
group by ph.eid, ph.name, ph.position, d.name
The syntax for joins is :
SELECT <COLUMNS>
FROM <Table>
INNER JOIN <Another_Table>
ON(<Relations>)
INNER JOIN <Another_table2>
ON(<Other Relations>
SELECT ph.name AS Name, ph.position AS Position,d.name AS Name, COUNT(app.appointmentId) AS Appointment
FROM physician AS ph INNER JOIN works_in AS w
ON ph.eid = w.department INNER JOIN department d
ON d.eid = w.department INNER JOIN appointment app ON ph.eid = app.physician
GROUP BY ph.eid,ph.name,ph.position,d.name

Selecting single column multiple times based on different conditions

I have written a SQL query to retrieve required data and it looks like given below:
SELECT distinct p.person_id,p.birth_date,p.gender_code,
wm_concat(distinct r.race_code) as race_code,p.hispanic_latino_code,
c.clinically_diagnosed_code,
wm_concat(distinct c.characteristic_code) as chara_codes,
p.prev_adopted_code,p.age_adopted,
FIRST_VALUE(pe.removed_date) OVER (ORDER BY pe.removed_date),
count(pe.removed_date) as removal_count,
LAST_VALUE(pe.discharge_date) OVER (ORDER BY pe.discharge_date),
LAST_VALUE(pe.removed_date) OVER (ORDER BY pe.removed_date) as latest_removal_date,pe.created_date,
pe.removal_circumstance_code,wm_concat(distinct rr.removal_reason_code) as removal_reasons,
ps.placement_type_code,ps.icpc_placement_flag,pe.caretaker_structure_code
FROM PERSON p left outer join RACE r on p.person_id = r.person_id
left outer join CHARACTERISTIC c on c.person_id = p.person_id
left outer join PLACEMENT_EPISODE pe on p.person_id = pe.child_id
left outer join PLACEMENT_SETTING ps on p.person_id = ps.child_id
left outer join REMOVAL_REASON rr on pe.placement_episode_id = rr.placement_episode_id
GROUP BY p.person_id,p.birth_date,p.gender_code,p.hispanic_latino_code,
c.clinically_diagnosed_code,p.prev_adopted_code,p.age_adopted,pe.removed_date,
pe.discharge_date,pe.removed_date,pe.created_date,pe.removal_circumstance_code,
ps.placement_type_code,ps.icpc_placement_flag,pe.caretaker_structure_code
ORDER BY p.person_id
In the above mentioned query, I have already selected birth date for a person. Now again in select clause I want to select birth_date for persons with following condition:
condition 1: p.person_id = pe.primary_caretaker_id
condition 2: p.person_id = pe.secondary_caretaker_id
Can someone tell me the way to select these fields(birth_date based on two different conditions) in the existing query?
Birth_date has been already selected once for individual person. Now I want to retrieve birth_date for primary_caretaker and secondary_caretaker.
You will need to join to the PERSON table twice more:
SELECT distinct p.person_id,p.birth_date,p.gender_code,
wm_concat(distinct r.race_code) as race_code,p.hispanic_latino_code,
c.clinically_diagnosed_code,
wm_concat(distinct c.characteristic_code) as chara_codes,
p.prev_adopted_code,p.age_adopted,
FIRST_VALUE(pe.removed_date) OVER (ORDER BY pe.removed_date),
count(pe.removed_date) as removal_count,
LAST_VALUE(pe.discharge_date) OVER (ORDER BY pe.discharge_date),
LAST_VALUE(pe.removed_date) OVER (ORDER BY pe.removed_date) as latest_removal_date,
pe.created_date,
pe.removal_circumstance_code,wm_concat(distinct rr.removal_reason_code) as removal_reasons,
ps.placement_type_code,ps.icpc_placement_flag,pe.caretaker_structure_code,
primCare.birth_date as primary_carer_birth_date,
secCare.birth_date as secondary_carer_birth_date,
FROM PERSON p left outer join RACE r on p.person_id = r.person_id
left outer join PERSON primCare on primCare.person_id = pe.primary_caretaker_id
left outer join PERSON secCare on secCare.person_id = pe.secondary_caretaker_id
left outer join CHARACTERISTIC c on c.person_id = p.person_id
left outer join PLACEMENT_EPISODE pe on p.person_id = pe.child_id
left outer join PLACEMENT_SETTING ps on p.person_id = ps.child_id
left outer join REMOVAL_REASON rr on pe.placement_episode_id = rr.placement_episode_id
GROUP BY p.person_id,p.birth_date,p.gender_code,p.hispanic_latino_code,
c.clinically_diagnosed_code,p.prev_adopted_code,p.age_adopted,pe.removed_date,
pe.discharge_date,pe.removed_date,pe.created_date,pe.removal_circumstance_code,
ps.placement_type_code,ps.icpc_placement_flag,pe.caretaker_structure_code, primCare.birth_date, secCare.birth_date
ORDER BY p.person_id

pass results of one query into another in SQL

I have two queries:
SELECT g.id FROM "group" g INNER JOIN group_role gr on g.id = gr.group_fk
INNER JOIN role_details rd on rd.group_role_fk = gr.id
INNER JOIN mandate m on m.role_details_fk = rd.id where m.id = x
and
SELECT p.id, p.name, g.name, g.id
FROM person p INNER JOIN position pos on p.id = pos.person_fk
INNER JOIN role_details rd on rd.id = pos.role_details_fk
INNER JOIN group_role gr on gr.id = rd.group_role_fk
INNER JOIN "group" g on g.id = gr.group_fk
WHERE g.id = y
I would like to be able to pass g.id into the second query so that for a given "x", I get p.id, p.name, g.name, g.id returned. How can I do this? Can it be done with more joins?
You can nest your queries like this, called Sub Queries, assumed both queries are working and the subquery only returns a single value.
SELECT p.id, p.name, g.name, g.id
FROM person p INNER JOIN position pos on p.id = pos.person_fk
INNER JOIN role_details rd on rd.id = pos.role_details_fk
INNER JOIN group_role gr on gr.id = rd.group_role_fk
INNER JOIN "group" g on g.id = gr.group_fk
WHERE g.id = (SELECT g.id FROM "group" g INNER JOIN group_role gr on g.id = gr.group_fk
INNER JOIN role_details rd on rd.group_role_fk = gr.id
INNER JOIN mandate m on m.role_details_fk = rd.id where m.id = x)
The easiest way would be to use a subquery like
SELECT p.id, p.name, g.name, g.id
FROM person p INNER JOIN position pos on p.id = pos.person_fk
INNER JOIN role_details rd on rd.id = pos.role_details_fk
INNER JOIN group_role gr on gr.id = rd.group_role_fk
INNER JOIN "group" g on g.id = gr.group_fk
WHERE g.id IN (SELECT g2.id FROM "group" g2 INNER JOIN group_role gr on g2.id = gr.group_fk
INNER JOIN role_details rd on rd.group_role_fk = gr.id
INNER JOIN mandate m on m.role_details_fk = rd.id where m.id = x)
Take care to use different aliases in the subquery unless you want to address the exact row you are looking at in the outer query.
To avoid the subquery you can reformulate the query using more joins - possibly joining the same table more than once using different aliases. Depending on the DBMS this might gain you some performance.

Where Exists returning all rows

My where exists clause isn't working. What trivial thing am I missing?
select * from patient as p
where exists
(
select p.patientid, count(*) from tblclaims as c
inner join patient as p on p.patientid=c.patientid
and p.admissiondate = c.admissiondate
and p.dischargedate = c.dischargedate
group by p.patientid
having count(*)>500
)
patient and tblclaims are joined together by the three-field composite key as as you can see in the query.
The count(*) from tblclaims as c is unnecessary and could be throwing the query off.
Also, you have no WHERE clause joining patient p to your exists clause.
Not to mention you use p as an alias in both the main query and the exists clause, which is just confusing.
You probably want something like:
select * from patient
where exists
(
select p.patientid
from tblclaims as c
inner join patient as p on p.patientid=c.patientid
and p.admissiondate = c.admissiondate
and p.dischargedate = c.dischargedate
where patient.patientid = p.patientid
group by p.patientid
having count(*)>500
)
You don't need to use the inner join in the sub-query at all; that is actually the cause of your extra results. You should be referencing the "p" in the outer query.
select * from patient as p
where exists
(
select 1 from tblclaims as c
where p.patientid = c.patientid
and p.admissiondate = c.admissiondate
and p.dischargedate = c.dischargedate
group by c.patientid
having count(*)>500
)
I'm not much of a fan of exists. Maybe you can use other functions. Try this:
select * from patient as p
where patientid IN
(
select p.patientid from tblclaims as c
inner join patient as p on p.patientid=c.patientid
and p.admissiondate = c.admissiondate
and p.dischargedate = c.dischargedate
group by p.patientid
having count(*)>500
)