SQL Server中的JOIN / LEFT JOIN冲突

时间:2013-02-20 10:13:04

标签: sql sql-server

我有一个棘手的问题。我需要选择2种类型的管理员组成员的所有最新版本。这是查询:

SELECT refGroup.*
FROM tblSystemAdministratorGroups refGroup
JOIN tblGroup refMem ON refGroup.AttributeValue = refMem.ObjectUID

此查询将返回所有管理员组。下一步将是获得这些组的成员。由于我有两种类型的会员资格(明确,计算),我将不得不使用LEFT JOIN来确保我不排除任何行。

SELECT refGroup.*
FROM tblSystemAdministratorGroups refGroup
-- The JOIN bellow can be excluded but it is here just to clarify the architecture
JOIN tblGroup refMem ON refGroup.AttributeValue = refMem.ObjectUID
LEFT JOIN tblGroup_ComputedMember cm ON refMem.ObjectUID = cm.GroupObjectID
LEFT JOIN tblGroup_ExplicitMember em ON refMem.ObjectUID = em.GroupObjectID

拼图的最后一部分是获取每个成员的最新版本。为此,我必须使用JOIN来排除旧版本:

JOIN (
    SELECT MAX([ID]) MaxId 
    FROM [OmadaReporting].[dbo].tblGroup_ComputedMember 
    GROUP BY ObjectID  
) MostRecentCM ON MostRecentCM.MaxId = cm.Id

JOIN (
    SELECT MAX([ID]) MaxId 
    FROM [OmadaReporting].[dbo].tblGroup_ExplicitMember 
    GROUP BY ObjectID  
) MostRecentEM ON MostRecentEM.MaxId = em.Id

完整查询将是:

SELECT refGroup.*
FROM tblSystemAdministratorGroups refGroup
JOIN tblGroup refMem ON refGroup.AttributeValue = refMem.ObjectUID
LEFT JOIN tblGroup_ComputedMember cm ON refMem.ObjectUID = cm.GroupObjectID
JOIN (
    SELECT MAX([ID]) MaxId 
    FROM [OmadaReporting].[dbo].tblGroup_ComputedMember 
    GROUP BY ObjectID  
) MostRecentCM ON MostRecentCM.MaxId = cm.Id
LEFT JOIN tblGroup_ExplicitMember em ON refMem.ObjectUID = em.GroupObjectID
JOIN (
    SELECT MAX([ID]) MaxId 
    FROM [OmadaReporting].[dbo].tblGroup_ExplicitMember 
    GROUP BY ObjectID  
) MostRecentEM ON MostRecentEM.MaxId = em.Id

问题很明显:排除旧版本的2 JOIN也适用于select语句,显然没有返回任何行。什么是逃避这种情况并返回预期值的最佳解决方案?

2 个答案:

答案 0 :(得分:2)

在最后两个连接中使用L​​EFT连接怎么样?

LEFT JOIN (
    SELECT MAX([ID]) MaxId 
    FROM [OmadaReporting].[dbo].tblGroup_ComputedMember 
    GROUP BY ObjectID  
) MostRecentCM ON MostRecentCM.MaxId = cm.Id

然后在Where子句中将过滤值视为:

WHERE MostRecentCM.MaxId IS NOT NULL 
      OR
      MostRecentEM.MaxId IS NOT NULL

答案 1 :(得分:2)

SELECT refGroup.*
FROM tblSystemAdministratorGroups refGroup
JOIN tblGroup refMem ON refGroup.AttributeValue = refMem.ObjectUID
LEFT JOIN (
    select GroupObjectID, ID, max(ID) over (partition by ObjectID) as maxID
    from tblGroup_ComputedMember
) cm ON refMem.ObjectUID = cm.GroupObjectID and cm.ID = cm.maxID
LEFT JOIN (
    select GroupObjectID, ID, max(ID) over (partition by ObjectID) as maxID
    from tblGroup_ExplicitMember
) em ON refMem.ObjectUID = em.GroupObjectID and em.ID = em.maxID
where cm.ID = cm.MaxID