SQL two multi-row counts in one query - sql

I have got two queries:
select m.name, count(distinct a.kursnr)
from trainer t
left outer join mitarbeiter m
on t.svnr = m.svnr
left outer join einzeltraining e
on t.svnr = e.trainer
left outer join abhaltung a
on t.svnr = a.trainer
group by m.name, t.svnr;
select m.name, count(e.trainer)
from trainer t
left outer join mitarbeiter m
on t.svnr = m.svnr
left outer join einzeltraining e
on e.trainer = t.svnr
group by m.name, e.trainer;
The first one returns the correct number of courses (kursnr) and the second number the correct number of individual classes (einzeltraining) hold by a trainer. However, I cannot make one SQL statement which shows both values in one table. Any help would be appreciated. Thank you.

While there is likely a more efficient way to do this, I wanted to show you the easy way to combine any two queries that share a common field such as this:
select coalesce(q2.name, q1.name) As Name, q1.KursnrCount, q2.TrainerCount
from
( --original first query
select m.name, count(distinct a.kursnr) as KursnrCount
from trainer t
left outer join abhaltung a
on t.svnr = a.trainer
left outer join mitarbeiter m
on t.svnr = m.svnr
left outer join einzeltraining e on svnr = e.trainer
group by m.name, t.svnr
) q1
full join
( --original second query
select count(e.trainer) as TrainerCount, m.name
from trainer t
left outer join einzeltraining e
on e.trainer = t.svnr
left outer join mitarbeiter m
on t.svnr = m.svnr
group by e.trainer, m.name
) q2 on q2.name = q1.name
You could also use an inner join or left join, instead of a full join, depending on how the name fields from those queries match up.

Related

Left join with multiple inner join

How can we make multiple left and inner join in SQL Server
Following query not returning all Employees because of Inner join
SELECT * from Employee E
LEFT JOIN Participants P on E.EmpID=P.EmpID
INNER JOIN HRDetails H on D. DeptID=H.DeptID
Left JOIN SalaryDetails S on S.participantID=P.participantID
You have used an alias D. which does not refer to any table, this may cause error.
But to answer your question I think inner join would reduce the number of rows if not all DeptID matches between two tables.

Column '' in field list is ambiguous. (when JOIN ON)

Column 'company_id' in field list is ambiguous
It does not seem "ambiguous", I have no idea where I should fix it:
SELECT company_id, companies.name
FROM company_contracts AS contracts
LEFT OUTER JOIN companies ON companies.id = contracts.company_id
LEFT OUTER JOIN order_logs AS logs ON companies.id = logs.company_id;
Because company_id appears on both table company_contracts and order_logs,you need to specify it
SELECT contracts.company_id,c1.name
FROM company_contracts as contracts
LEFT OUTER JOIN companies as c1 on c1.id = contracts.company_id
LEFT OUTER JOIN order_logs as logs on c1.id = logs.company_id;
You should qualify all columns names in such a query. In addition, if you really want outer joins, the second join condition should refer to the first table, not the second:
SELECT cc.company_id, c.name
FROM company_contracts cc LEFT OUTER JOIN
companies c
ON c.id = cc.company_id LEFT OUTER JOIN
order_logs ol
ON cc.company_id = ol.company_id;
Or, more likely, you want to keep all companies and the query should look like:
SELECT c.id, c.name
FROM companies c LEFT OUTER JOIN
company_contracts cc
ON c.id = cc.company_id LEFT OUTER JOIN
order_logs ol
ON c.id = ol.company_id;

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

outer join on junction table

I'm using mssql
How do I do a outer join on three tables, one of which is a junction table?
There can be nulls in the menu or product tables and I need these included in the result.
SELECT *
from [web].[dbo].[tblMenus]
left outer JOIN [web].[dbo].[tblProductsRelMenus]
on [tblMenus].Id = [tblProductsRelMenus].MenuId
left outer JOIN [web].[dbo].[tblProducts]
on [tblProductsRelMenus].ProductId = [tblProducts].ProductId
This doesn't give menu nulls, and if I change the second left to a right, I loose the product nulls...
What is the correct way to do this?
Perhaps you are looking for a full outer join
SELECT *
from [web].[dbo].[tblMenus]
full outer JOIN [web].[dbo].[tblProductsRelMenus]
on [tblMenus].Id = [tblProductsRelMenus].MenuId
full outer JOIN [web].[dbo].[tblProducts]
on [tblProductsRelMenus].ProductId = [tblProducts].ProductId
SELECT *
FROM
[web].[dbo].[tblMenus]
LEFT JOIN
[web].[dbo].[tblProductsRelMenus]
RIGHT OUTER JOIN
[web].[dbo].[tblProducts]
ON [tblProductsRelMenus].ProductId = [tblProducts].ProductId
ON [tblMenus].Id = [tblProductsRelMenus].MenuId

What kind of SQL join would this be?

I need to go to two tables to get the appropriate info
exp_member_groups
-group_id
-group_title
exp_members
-member_id
-group_id
I have the appropriate member_id
So I need to check the members table, get the group_id, then go to the groups table and match up the group_id and get the group_title from that.
INNER JOIN:
SELECT exp_member_groups.group_title
FROM exp_members
INNER JOIN exp_member_groups ON exp_members.group_id = exp_member_groups.group_id
WHERE exp_members.member_id = #memberId
SELECT g.group_title
FROM exp_members m
JOIN exp_member_groups g ON m.group_id = g.group_id
WHERE m.member_id = #YourMemberId
If there is always a matching group, or you only want rows where it is, then it would be an INNER JOIN:
SELECT g.group_title
FROM exp_members m
INNER JOIN
exp_member_groups g
ON m.group_id = g.group_id
WHERE m.member_id = #member_id
If you want rows even where group_id doesn't match, then it is a LEFT JOIN - replace INNER JOIN with LEFT JOIN in the above.