基于 SQL Server 2008 中列值的内部联接

Posted

技术标签:

【中文标题】基于 SQL Server 2008 中列值的内部联接【英文标题】:Inner Join based on column value in SQL Server 2008 【发布时间】:2015-02-03 23:11:43 【问题描述】:

我想根据列值连接两个表

如果pm.ServiceLevelID 的值为1 或NULL,则在u.FacilityId 上进行内连接 如果pm.ServiceLevelID 的值为2,则在u.FacilityServiceId 上进行内连接

pm, u 这两个表有这些列:

ProviderMessages
  MessageID, FacilityServiceID, ServiceLevelID, FacilityID, ProviderTypeID

User_FA
  FacilityServiceId, UserFacilityID, FacilityId

目前,我有这个INNER JOIN

SELECT DISTINCT 
    MessageID, UserFacilityID, 9    
FROM 
    #ProviderMessages   
INNER JOIN 
    #User_FA ON (#User_FA.FacilityId = #ProviderMessages.FacilityID OR  
                                   #ProviderMessages.FacilityID IS NULL)
             AND (#User_FA.FacilityServiceId = #ProviderMessages.FacilityServiceID)

【问题讨论】:

使用Case 我想知道这个问题有什么不好。 -5,真的吗? 【参考方案1】:
SELECT DISTINCT MessageID, UserFacilityID, 9    
 FROM #ProviderMessages   
 JOIN #User_FA 
   ON #ProviderMessages.ServiceLevelID  in (null,1,2) 
  and (  ( #ProviderMessages.ServiceLevelID  in (null,1) 
           and #User_FA.FacilityId = #ProviderMessages.FacilityID) 
         or 
         ( ProviderMessages.ServiceLevelID = 2
           AND #User_FA.FacilityServiceId = #ProviderMessages.FacilityServiceID) 
      ) 

【讨论】:

添加子句#ProviderMessages,ServiceLevelID in (null,1,2) and有什么好处? @Beth 我认为这不会造成伤害。而且我认为它可以让查询优化器提前抛出一些东西。 猜这取决于规模。不过,我怀疑还有其他价值。 @Beth 为什么猜?检查查询计划。它要么在 ServiceLevelID 早期进行索引搜索,要么不进行。更快的查询没有价值?【参考方案2】:

这是您的查询,使用表别名使其更具可读性:

SELECT DISTINCT MessageID, UserFacilityID, 9    
FROM #ProviderMessages m INNER JOI
     #User_FA u
    ON (u.FacilityId = m.FacilityID OR m.FacilityID IS NULL) AND
       u.FacilityServiceId = m.FacilityServiceID;

你想要的逻辑是

SELECT DISTINCT MessageID, UserFacilityID, 9    
FROM #ProviderMessages m INNER JOIN
     #User_FA u
    ON ((pm.ServiceLevelID = 1 or pm.ServiceLevelID is null) AND pm.FacilityId = u.facilityId) or
       (pm.ServiceLevelID = 2 and pm.FacilityServiceID = m.FacilityServiceID)

【讨论】:

输出怎么错了?这就是你所要求的。 输出是什么,你期望它是什么?一个简单的“这不是我想要的”并不能帮助任何人获得你真正想要的解决方案。【参考方案3】:

我不确定我是否理解得很好,但在我之前的工作中,我们也遇到过类似的情况。 请试试这个:

SELECT DISTINCT 
    MessageID, UserFacilityID, 9    
FROM 
    #ProviderMessages   
    INNER JOIN #User_FA 
        ON (CASE WHEN ISNULL(#ProviderMessages.ServiceLevelID, 1) = 1
                 THEN #ProviderMessages.FacilityID
                 ELSE #ProviderMessages.FacilityServiceId
            END)
            = (CASE WHEN ISNULL(#ProviderMessages.ServiceLevelID, 1) = 1
                 THEN #User_FA.FacilityId
                 ELSE #User_FA.FacilityServiceId
              END)

希望对你有帮助。

【讨论】:

【参考方案4】:

合并两个结果


SELECT DISTINCT MessageID, UserFacilityID, 9    
FROM #ProviderMessages   
INNER JOIN #User_FA ON (#User_FA.FacilityId = #ProviderMessages.FacilityID OR  
                                   #ProviderMessages.FacilityID IS NULL)
WHERE #ProviderMessages.ServiceLevel <> 2

UNION

SELECT DISTINCT MessageID, UserFacilityID, 9    
FROM #ProviderMessages   
INNER JOIN #User_FA ON (#User_FA.FacilityServiceId = #ProviderMessages.FacilityServiceID)
WHERE #ProviderMessages.ServiceLevel = 2

【讨论】:

以上是关于基于 SQL Server 2008 中列值的内部联接的主要内容,如果未能解决你的问题,请参考以下文章

基于列值的 Foreach 内部的 Foreach

Spark Scala聚合函数,用于查找组中列值的出现次数

如何在 sql server 2008 中交换列值?

sql server 如何限制某一列值的数值长度 如:在某一数据库中图书证号必须是6位数字???谢谢啦

在 SQL Server 中,如何选择共享公共列值的行?

SQL查询以查找表中列值多次出现的计数?