SQL-多表联接并选择条件上的第一条记录

SQL-多表联接并选择条件上的第一条记录,sql,sql-server,join,Sql,Sql Server,Join,我有以下表格: Projects (ID, Name, ManagerUser_ID) Users(ID, Name, Active) Delegates(ProjectID, UserID, OrderNo) ManagerUser_ID是项目的项目经理,是指向用户表的链接。但是,用户可以处于非活动状态。因此,委托表是一个多对多表,定义了可以访问项目数据的用户 我需要的是,假设经理处于非活动状态,为处于活动状态的项目选择第一个代理。OrderNo字段指定代理1的优先顺序 一些样本数据: Pr

我有以下表格:

Projects (ID, Name, ManagerUser_ID)
Users(ID, Name, Active)
Delegates(ProjectID, UserID, OrderNo)
ManagerUser_ID是项目的项目经理,是指向用户表的链接。但是,用户可以处于非活动状态。因此,委托表是一个多对多表,定义了可以访问项目数据的用户

我需要的是,假设经理处于非活动状态,为处于活动状态的项目选择第一个代理。OrderNo字段指定代理1的优先顺序

一些样本数据:

Project
1, Project1, 2
2, Project2, 4
3, Project3, 1

Users
1, Joe, true
2, John, false
3, Dave, true
4, Bob, false

Delegates
1, 4, 1
1, 1, 2
1, 3, 3
2, 2, 1
2, 4, 2
2, 3, 3
因此,我的查询输出需要显示:

Project1, Joe
Project2, Dave
Project3, Joe

显示每个项目的项目和用户,如果ManagerUser\u ID处于非活动状态,则选择代理中处于活动状态的OrderNo最低的用户。

我想应该是这样的。其思想是使用left join进行额外的连接,以查找较早的有效行。如果您可以找到该行,那么显然您正在构造的当前行不是您想要的行:

select p.Name,m.Name from Projects p inner join Users m on p.ManagerUser_ID = m.ID and m.Active = 1
union all
select
    p.Name,
    u.Name
from
    Projects p
        inner join
    Delegates d
        on
            p.ID = d.ProjectID
        inner join
    Users u
        on
            d.UserID = u.ID and
            u.Active = 1
        left join
    Delegates d_anti
        inner join
    Users u_anti
        on
            d_anti.UserID = u_anti.ID and
            u_anti.Active = 1
        on
            p.ID = d_anti.ProjectID and
            d_anti.OrderNo < d.OrderNo
where
    u_anti.ID is null

这似乎是使用窗口函数实现的

SELECT  P.Name, ISNULL(U.Name, FirstDelegate.Name) AS ProjManager
FROM    Projects P LEFT OUTER JOIN
        Users U ON P.ManagerUser_ID = U.ID AND U.Active = 1 LEFT OUTER JOIN
        (
            SELECT * FROM
            (
                SELECT D.ProjectID, 
                       US.Name, 
                       ROW_NUMBER() OVER (PARTITION BY ProjectID ORDER BY OrderNo) AS SeqNo
                FROM  Delegates D INNER JOIN
                      Users US ON D.UserID = US.ID
                WHERE US.Active = 1
            ) AS Del
            WHERE Del.SeqNo = 1
        ) AS FirstDelegate ON P.ID = FirstDelegate.ProjectID

不幸的是,这无法检索项目的第一个活动委托。这将列出项目的所有用户以及订单号。需要在某个地方进行调用,以将结果集限制为活动的最低订单号。这看起来非常接近,我明天必须检查它。但是,final ON子句不正确-u_anti.OrderNoSelect projectName, userName From ( Select projectName, userName, row_number() over (partition by projectName order by priority ASC) as rank From ( SELECT p.name as projectName, u.name as userName, 1 as priority FROM projects p INNER JOIN users u ON u.active = true and u.id = p.ManagerUser_ID UNION SELECT TOP(1) p.name, u.name, 2 FROM Delegates d INNER JOIN projects p ON p.id = d.projectId INNER JOIN users u ON u.id = d.userId Where u.active = true Order by u.OrderNo ASC ) ) where rank = 1
SELECT  P.Name, ISNULL(U.Name, FirstDelegate.Name) AS ProjManager
FROM    Projects P LEFT OUTER JOIN
        Users U ON P.ManagerUser_ID = U.ID AND U.Active = 1 LEFT OUTER JOIN
        (
            SELECT * FROM
            (
                SELECT D.ProjectID, 
                       US.Name, 
                       ROW_NUMBER() OVER (PARTITION BY ProjectID ORDER BY OrderNo) AS SeqNo
                FROM  Delegates D INNER JOIN
                      Users US ON D.UserID = US.ID
                WHERE US.Active = 1
            ) AS Del
            WHERE Del.SeqNo = 1
        ) AS FirstDelegate ON P.ID = FirstDelegate.ProjectID