SQL JOIN WITH OR Condition

☆樱花仙子☆ 提交于 2019-12-19 09:08:10

问题


I have a table say Cases, which is using reference from Workers for three columns. Also there is one table Company to which workers belongs.

Below is the schema:

Cases [ CaseID, CaseNumber, Worker1, Worker2, Worker3 ] 
Workers [ WorkerID, ComapnyID]
Company [CompanyID, CompanyName]

Now I need case count for each company. So is it possible to make one join with workers and map all Worker1, Worker2 and Worker3 columns? Is there any better option and performance impact?

Note: Two workers from one company can work on single case, or all the workers can be from different companies.


回答1:


Although join conditions are commonly equality checks, there's nothing special about them - any valid SQL condition could be used for performing a join. In you case, an IN condition seems appropriate:

SELECT   CompanyName, COUNT(DISTINCT CaseID)
FROM     Company co
JOIN     Workers w ON co.CompanyId = w.CompanyId
JOIN     Cases ca ON w.WorkerId IN (ca.Worker1, ca.Worker2, ca.Worker3)
GROUP BY CompanyName



回答2:


select
    C.CompanyID, C.CompanyName, count(distinct CaseID)
from Company C
    inner join Workers W
        on C.CompanyID = W.WorkerID
    inner join (
        select CaseId, WorkerId = Worker1 from Cases where Worker1 is not null
        UNION ALL
        select CaseId, WorkerId = Worker2 from Cases where Worker2 is not null
        UNION ALL
        select CaseId, WorkerId = Worker3 from Cases where Worker3 is not null
        ) CW
        on W.WorkerID = CW.WorkerID
group by C.CompanyID, C.CompanyName



回答3:


I'd recommend changing your schema a little like so:

cases - caseid, casenumber
workers - workerid, companyid
cases_workers - caseid, workerid
company - companyid, companyname

If you had it this way, you could write:

select companyname, count(*)
from company c
inner join workers w on c.companyid = w.companyid
inner join cases_workers cw on w.workerid = cw.workerid
group by companyname

EDIT:

If you cannot change schema, use some of the good queries already mentioned by other commenters. Here's my version:

with caselist (
  select worker1 as worker from cases union all
  select worker2 as worker from cases union all
  select worker3 as worker from cases
)
select companyname, count(*)
from company c
inner join workers w on c.companyid = w.companyid
inner join caselist cl on w.workerid = cl.worker
group by companyname


来源:https://stackoverflow.com/questions/34194658/sql-join-with-or-condition

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!