2013-02-20 6 views
1

У меня сложный запрос. Мне нужно выбрать все последние версии двух типов членов групп администраторов. Вот запрос:JOIN/LEFT JOIN конфликт в SQL Server

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 и явно не возвращаются строки. Что было бы лучшим решением избежать такой ситуации и вернуть намеченные ценности?

+0

мусульманин означает тот, кто угнетает, кстати, в отличие от мусульманина, что означает тот, кто подчиняется, к Богу. – muhmud

ответ

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 
2

Как насчет использования LEFT в ваших последних двух соединениях?

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

И тогда в тех случаях, когда значения пункта фильтра, как:

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