Can you assist in re-writing this into joins?
select * from users where users.advised_by in (
select p.id
from advisors p
join advisor_members m on p.id = m.advisor_id
join representatives r on m.user_id=r.user_id
where m.memeber_type='Advisor'
)
This is part of 200+ row query and that in() statement is hard to maintain when there are changes.
you should use a proper on clause
select *
from users
inner join
(
select p.id
from advisors p
join advisor_members m on p.id = m.advisor_id
join representatives r on m.user_id=r.user_id
where m.memeber_type='Advisor'
) t on users.advised_by = t.id
/*Option 1 */
SELECT *
FROM users usr
INNER JOIN
(
SELECT p.id AS advisor_id
FROM advisors p
JOIN advisor_members m
ON p.id = m.advisor_id
JOIN representatives r
ON m.user_id=r.user_id
WHERE m.memeber_type='Advisor' ) T2 usr.advised_by = t2.advisor_id
/*Option2 -- */
SELECT *
FROM users usr
INNER JOIN advisors p
ON usr.advised_by=p.id
JOIN
(
SELECT *
FROM advisor_members
WHERE m.memeber_type='Advisor') m
ON p.id = m.advisor_id
JOIN representatives r
ON m.user_id=r.user_id
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
This subquery produces the correct table. But now I want to get the average of the averages, and I'm getting an error "Missing FROM-clause entry for table "c"".
SELECT
c.name,
AVG(avgvalue)
FROM
(
SELECT
c.name,
p.name,
AVG(a."value") AS avgvalue
FROM answers a INNER JOIN survey_responses sr ON sr.id = a.survey_response_id AND a.question_id = 13
INNER JOIN answers category_answer ON category_answer.survey_response_id = sr.id AND category_answer.question_id = 264
INNER JOIN answers_categories ac ON category_answer.id = ac.answer_id
INNER JOIN categories c ON c.id = ac.category_id
INNER JOIN products p ON p.id = a.product_id
WHERE c.name IN ('Accounting')
GROUP BY c.name, p."name"
HAVING count(p.name)>10
) as ProductAverages
GROUP BY c.name;
You are naming the ProductAverages, so your table aliases should reference it, not c - which can be used only in the inner query:
SELECT
name, -- Here
AVG(avgvalue)
FROM
(
SELECT
c.name,
p.name,
AVG(a."value") AS avgvalue
FROM answers a INNER JOIN survey_responses sr ON sr.id = a.survey_response_id AND a.question_id = 13
INNER JOIN answers category_answer ON category_answer.survey_response_id = sr.id AND category_answer.question_id = 264
INNER JOIN answers_categories ac ON category_answer.id = ac.answer_id
INNER JOIN categories c ON c.id = ac.category_id
INNER JOIN products p ON p.id = a.product_id
WHERE c.name IN ('Accounting')
GROUP BY c.name, p."name"
HAVING count(p.name)>10
) as ProductAverages
GROUP BY name; -- and here
I have this select statement:
select m.title, m.category_code, c.company_name, wm_concat(d.director_name),
wm_concat(a.actor_name) as actors
from
actors a
inner join actor_in_movies aim
on aim.actor_id = a.actor_id
inner join movies m
on m.movie_id = aim.movie_id
inner join movie_directors md
on md.movie_id = m.movie_id
inner join directors d
on d.director_id = md.director_id
inner join companies c
on c.company_id = d.company_id
group by m.title, m.category_code, c.company_name;
and it returns the same directors name one time for every actor....any way around this happening?
Tried this too:
select m.title, cat.description, c.company_name, wm_concat(d.director_name),
wm_concat(a.actor_name) as actors
from
movie_categories cat
inner join movies m
on m.category_code = cat.category_code
inner join movie_directors md
on md.movie_id = m.movie_id
inner join directors d
on d.director_id = md.director_id
inner join companies c
on c.company_id = d.company_id
inner join actor_in_movies aim
on aim.movie_id = m.movie_id
inner join actors a
on a.actor_id = aim.actor_id
group by m.title, cat.description, c.company_name;
with the same results
EDIT:
Guess I just needed to think more, used distinct and got it!
select m.title, cat.description, c.company_name, wm_concat(distinct
d.director_name),
wm_concat(a.actor_name) as actors
from
movie_categories cat
inner join movies m
on m.category_code = cat.category_code
inner join movie_directors md
on md.movie_id = m.movie_id
inner join directors d
on d.director_id = md.director_id
inner join companies c
on c.company_id = d.company_id
inner join actor_in_movies aim
on aim.movie_id = m.movie_id
inner join actors a
on a.actor_id = aim.actor_id
group by m.title, cat.description, c.company_name;
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]