【问题标题】:SQL JOIN WITH OR ConditionSQL JOIN WITH OR 条件
【发布时间】:2016-03-15 15:52:44
【问题描述】:

我有一张表说 Cases,它使用来自 Workers 的参考来表示三列。还有一张 Company 员工所属的表。

下面是架构:

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

现在我需要每个公司的案例计数。 那么是否可以与工人进行一次联接并映射所有 Worker1Worker2Worker3 列?有没有更好的选择和性能影响?

注意:一个公司的两名工人可以处理一个案件,或者所有工人都来自不同的公司。

【问题讨论】:

  • 首先,设计有问题。你应该有一个像CaseWorker (CaseID, WokerID) 这样的连接表。

标签: sql sql-server select sql-server-2012


【解决方案1】:

虽然连接条件通常是相等性检查,但它们并没有什么特别之处 - 任何有效的 SQL 条件都可用于执行连接。在您的情况下,IN 条件似乎合适:

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

【讨论】:

  • 我实际上比我更喜欢这个,因为它做到了罐头上所说的那样,没有别的。虽然错过了一个小组。
  • @IanYates 哎呀!不知道那里发生了什么。你是对的,当然。我已经编辑了group by in.
  • 这是一个简洁明了的查询!酷!
【解决方案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

【讨论】:

  • 查看其他有关架构更改的 cmets。但是如果你不能改变它,你至少可以作弊和反透视(语法我永远记不起我的头顶,所以我改用 UNION ALLs)来虚拟地制作桌子
【解决方案3】:

我建议您像这样更改您的架构:

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

如果你有这种方式,你可以写:

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

编辑:

如果您无法更改架构,请使用其他评论者已经提到的一些好的查询。这是我的版本:

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

【讨论】:

  • 同意 - 架构更改是正确的方法。但并非总是可能的:(
  • @IanYates,是的,我同意你的看法。让我编辑我的答案并添加可用于当前架构的查询
  • 抱歉,我无法更改架构,因为它已经构建并且数据库正在生产中。
  • @dotNetAddict 这是可以理解的。我已经适当地编辑了我的答案,使查询与我写的前一个查询有点相似。还要记住,有一天您将不得不更改架构;早做可能比晚做更好。
猜你喜欢
  • 2020-05-17
  • 2016-12-20
  • 1970-01-01
  • 2010-12-31
  • 1970-01-01
  • 2013-09-23
  • 1970-01-01
  • 2017-07-31
  • 2023-03-12
相关资源
最近更新 更多