Sql 连接具有不同的最高排名行的表

Sql 连接具有不同的最高排名行的表,sql,sql-server,distinct,Sql,Sql Server,Distinct,我有三个定义如下的表: [tbMember] memberID | memberName 1 | John 2 | Peter [tbGroup] groupID | groupName 1 | Alpha 2 | Beta 3 | Gamma [tbMemberGroupRelation] memberID | groupID | memberRank (larger number is higher) 1

我有三个定义如下的表:

[tbMember]
memberID | memberName
1        | John
2        | Peter

[tbGroup] 
groupID | groupName
1       | Alpha
2       | Beta
3       | Gamma    

[tbMemberGroupRelation]
memberID | groupID | memberRank (larger number is higher)
1        | 1       | 0
1        | 2       | 1
2        | 1       | 5
2        | 2       | 3
2        | 3       | 1
现在,我想执行一个表连接选择,以获得一个结果,该结果包含每行中排名最高的组的不同成员,对于上面给定的示例,查询结果应该是:

memberID | memberName | groupName | memberRank
1        | John       | Beta      | 1
2        | Peter      | Alpha     | 5
有没有一种方法可以像下面这样用一个SQL实现它

select * from tbMember m
    left join tbMemberGroupRelation mg on (m.MemberID = mg.MemberID and ......)
    left join tbGroup g on (mg.GroupID = g.GroupID)
如果无法在一个简单的查询中编写,则也欢迎使用任何其他解决方案

==========已更新=========

表中只允许有一个最高等级


一种解决方案是创建memberRank的倒序/秩,以便每个成员的最高秩始终等于1

这是我如何使用子查询实现的:

SELECT
    m.memberID,
    m.memberName,
    g.groupName,
    mg.memberRank
FROM
    tbMember m
LEFT JOIN
    (
    SELECT
        memberID,
        groupID,
        groupName,
        memberRank,
        RANK() OVER(PARTITION BY memberID ORDER BY memberRank DESC) AS invRank
    FROM
        tbMemberGroupRelation
    ) mg
    ON (mg.memberID = m.memberID)
    AND (mg.invRank = 1)
LEFT JOIN
    tbGroup g
    ON (g.groupID = mg.groupID);

一种解决方案是创建memberRank的倒序/秩,以便每个成员的最高秩始终等于1

这是我如何使用子查询实现的:

SELECT
    m.memberID,
    m.memberName,
    g.groupName,
    mg.memberRank
FROM
    tbMember m
LEFT JOIN
    (
    SELECT
        memberID,
        groupID,
        groupName,
        memberRank,
        RANK() OVER(PARTITION BY memberID ORDER BY memberRank DESC) AS invRank
    FROM
        tbMemberGroupRelation
    ) mg
    ON (mg.memberID = m.memberID)
    AND (mg.invRank = 1)
LEFT JOIN
    tbGroup g
    ON (g.groupID = mg.groupID);
另一种方法是:

SELECT
    M.memberID,
    M.memberName,
    G.groupName,
    MG.memberRank
FROM
    Member M
LEFT OUTER JOIN MemberGroup MG ON MG.memberID = M.memberID
LEFT OUTER JOIN MemberGroup MG2 ON
        MG2.memberID = M.memberID AND
        MG2.memberRank > MG.memberRank
INNER JOIN [Group] G ON G.groupid = MG.groupid
WHERE
    MG2.memberid IS NULL
由于索引等原因,在某些情况下可能会表现更好。

另一种方法:

SELECT
    M.memberID,
    M.memberName,
    G.groupName,
    MG.memberRank
FROM
    Member M
LEFT OUTER JOIN MemberGroup MG ON MG.memberID = M.memberID
LEFT OUTER JOIN MemberGroup MG2 ON
        MG2.memberID = M.memberID AND
        MG2.memberRank > MG.memberRank
INNER JOIN [Group] G ON G.groupid = MG.groupid
WHERE
    MG2.memberid IS NULL

由于索引等原因,在某些情况下可能会表现得更好。

如果该成员在两个不同的组中具有相同的等级,该怎么办?只允许有一个最高等级。更新在我原来的帖子@Tomh如果该成员在两个不同的组中具有相同的等级,该怎么办?只允许有一个最高等级。更新在我原来的帖子@TomHIt在从海量数据中选择时工作并具有良好的性能,在从海量数据中选择时工作并具有良好的性能。