【问题标题】:Joins on separate columns在单独的列上连接
【发布时间】:2020-08-19 19:13:29
【问题描述】:

我正在编写一个查询,它是更大数据提取查询的一部分。我坚持的部分最好解释如下:

Table1 (T1) 列

  • 位置 ID
  • 服务类别

Table3 (T3) 列

  • 位置 ID
  • 服务类别
  • 服务类型
  • 服务序列
  • 服务状态

Table6 (T6) 列

  • 位置 ID
  • 服务类型
  • 服务序列
  • 服务费率

T1 是主表。 T3 和 T1 使用 LocationID 和 ServiceCategory 连接。但是,这种组合在 T3 中可能存在重复项。因此,我正在使用:

LEFT JOIN(select distinct T3.LocationID,T3.ServiceCategory from Table3 where ServiceStatus in (2,3,4)) T3

ON T1.LocationID=T3.LocationID and T1.ServiceCategory=T3.ServiceCategory

当然,现在我没有 T3.ServiceType 来加入 Table6。当我最终进入 T3 和 T6 之间的连接时,我想保持 Table1 的记录数不变。我在进一步加入中使用 T6.ServiceRate 所以它对我的问题并不是特别重要。我基本上对表格的设计方式以及我需要如何创建连接感到困惑。

我有一个次要问题,表 3 中的 ServiceCategory 由两种类型的 ServiceType 记录共享。在 LocationID 中,我只希望在我的 SELECT 语句中检索其中一个 ServiceCategory 记录。区别在于 ServiceType 是 WI。我使用 LEFT JOIN 的原因是因为并非所有 T1.LocationID / T1.ServiceCategory 记录都会匹配,因此不可能有 INNER JOIN

我正在寻求解决这些问题的帮助。如果需要,很高兴分享一些示例数据。

样本数据:

【问题讨论】:

  • 关于您的第一个问题,T3 中的LocationIDServiceCategoryServiceType 是否有可能重复。如果没有重复,则只需将ServiceType 添加到您的LEFT JOIN (select distinct ...) 语句中。如果有重复,那么这些将反映在您的结果集中,因此不会保留 T1 行数。但这不是预期的行为吗?如果相同的LocIdServiceCategory 有两个不同的ServiceTypes,那么数据库引擎如何知道选择哪个ServiceType
  • 在一定程度上你是对的。使用所有三列将导致相同的记录数。但是,有一种情况,相同的 LocationID 可以有两个不同的 ServiceType 值(W 和 I),它们具有相同的 ServiceCategory。这是我要克服的第二个问题。
  • 另外,我在原始笔记中忘记了一些东西。 ServiceSequence 很重要。当我将它添加到我的 SELECT DISTINCT 时,我的记录数就会增加。 LocationID、ServiceCategory、ServiceType 和 ServiceSequence 的组合可能会产生额外的记录。如何从 JOIN 的结果中消除这些?
  • 我通过使用 max(ServiceSequence) 部分修复它(按 LocationID 分区,按 LocationID 的 ServiceCategory 顺序,ServiceCategory)作为 maxServiceSeq。如果 ServiceSequence 中有重复项,这让我只选择一条记录。我仍在尝试消除两个 ServiceType 记录共享相同 ServiceCategory 的情况。我可能必须在 SELECT 中使用 CASE。但我不确定如何让它在 LocationID 中工作。
  • 如果您显示一些示例数据和期望的结果,您的问题会更加清晰。

标签: sql-server join


【解决方案1】:

不确定,如果我理解正确的话。 你的意思是T3.ServiceType可以是WI

也许,您可以使用not EXISTS 添加一个构造:

SELECT
*
FROM
T1
LEFT JOIN(select distinct T3.LocationID,T3.ServiceCategory,T3 from Table3 where ServiceStatus in (2,3,4)) T3 
ON T1.LocationID=T3.LocationID and T1.ServiceCategory=T3.ServiceCategory

WHERE
(
T3.ServiceType = 'W' 
OR NOT EXISTS (SELECT TOP 1 1 from Table3 T3n WHERE T3n.ServiceStatus in (2,3,4) and T1.LocationID=T3n.LocationID and T1.ServiceCategory=T3n.ServiceCategory and T3n.ServiceType <> T3.ServiceType)
)

【讨论】:

  • 感谢您的建议。不幸的是,它消除了该特定 LocationIDWI 行。我无法弄清楚为什么会这样。
  • Hmmmm... 让我们再考虑一下 让 T3.Servicetype 为 I。这意味着:T3.ServiceType = 'W' -> FALSE 这意味着,这个子查询必须返回:SELECT TOP 1 1 from Table3 T3n WHERE T3n.ServiceStatus in (2,3,4) and T1.LocationID=T3n.LocationID and T1.ServiceCategory=T3n.ServiceCategory and T3n.ServiceType &lt;&gt; T3.ServiceType 也许你应该进一步检查这个子查询返回什么?
  • 你的逻辑是对的。今天早些时候我一定是草率地设置了 WHERE 条件。我又看了一遍,得到了我需要的结果。您查看子查询的建议被证明是有帮助的。问题解决了!非常感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 2016-05-08
  • 2015-09-21
  • 2020-03-08
  • 1970-01-01
  • 2020-10-14
  • 2021-11-23
  • 2019-12-17
  • 1970-01-01
相关资源
最近更新 更多