SQL查询:仅左连接返回交叉点

SQL查询:仅左连接返回交叉点,sql,left-join,Sql,Left Join,我一直在努力解决我认为是一个简单的SQL查询: SELECT resource.firstname, resource.lastname, resource.fte, project.name as project_name, role.name as role_name, assignment.startdate, assignment.enddate, assignment.numberofdaysperweek FROM resourc

我一直在努力解决我认为是一个简单的SQL查询:

SELECT 
  resource.firstname, 
  resource.lastname, 
  resource.fte, 
  project.name as project_name, 
  role.name as role_name, 
  assignment.startdate, 
  assignment.enddate, 
  assignment.numberofdaysperweek
FROM 
  resource
LEFT JOIN assignment ON resource.id = assignment.resource_id AND assignment.enddate < now()
LEFT JOIN project ON project.id = assignment.project_id 
LEFT JOIN role ON role.id = assignment.role_id
因此,我在这个查询中有4个表:资源被分配给项目,并被赋予该项目的特定角色


此查询的问题是,它将返回任何资源+任何分配已过期的资源的数据。enddate要将分配限制为每个资源的最新分配,你需要找到每个资源id的最新开始日期,并将内部连接返回分配表

SELECT  assignment.*
FROM    assignment
        INNER JOIN
        (   SELECT  assignment.resource_id, 
                    MAX(assignment.StartDate) AS StartDate
            FROM    assignment
            GROUP BY assignment.resource_id
        ) MaxAssignment
            ON assignment.resource_id = MaxAssignment.resource_id
            AND assignment.StartDate = MaxAssignment.StartDate;
由于您只想左键连接到该查询,因此需要将上面的全部内容移动到子查询中,并将整个子查询左键连接回主查询:

SELECT  resource.firstname, 
        resource.lastname, 
        resource.fte, 
        project.name as project_name, 
        role.name as role_name, 
        assignment.startdate, 
        assignment.enddate, 
        assignment.numberofdaysperweek
FROM    resource
        LEFT JOIN 
        (   SELECT  assignment.*
            FROM    assignment
                    INNER JOIN
                    (   SELECT  assignment.resource_id, 
                                MAX(assignment.StartDate) AS StartDate
                        FROM    assignment
                        GROUP BY assignment.resource_id
                    ) MaxAssignment
                        ON assignment.resource_id = MaxAssignment.resource_id
                        AND assignment.StartDate = MaxAssignment.StartDate
        ) assignment
            ON resource.id = assignment.resource_id 
            AND assignment.enddate < now()
        LEFT JOIN project 
            ON project.id = assignment.project_id 
        LEFT JOIN role 
            ON role.id = assignment.role_id;

要将分配限制为每个资源的最新分配,您需要找到每个资源的最新开始日期,并将内部连接返回分配表

SELECT  assignment.*
FROM    assignment
        INNER JOIN
        (   SELECT  assignment.resource_id, 
                    MAX(assignment.StartDate) AS StartDate
            FROM    assignment
            GROUP BY assignment.resource_id
        ) MaxAssignment
            ON assignment.resource_id = MaxAssignment.resource_id
            AND assignment.StartDate = MaxAssignment.StartDate;
由于您只想左键连接到该查询,因此需要将上面的全部内容移动到子查询中,并将整个子查询左键连接回主查询:

SELECT  resource.firstname, 
        resource.lastname, 
        resource.fte, 
        project.name as project_name, 
        role.name as role_name, 
        assignment.startdate, 
        assignment.enddate, 
        assignment.numberofdaysperweek
FROM    resource
        LEFT JOIN 
        (   SELECT  assignment.*
            FROM    assignment
                    INNER JOIN
                    (   SELECT  assignment.resource_id, 
                                MAX(assignment.StartDate) AS StartDate
                        FROM    assignment
                        GROUP BY assignment.resource_id
                    ) MaxAssignment
                        ON assignment.resource_id = MaxAssignment.resource_id
                        AND assignment.StartDate = MaxAssignment.StartDate
        ) assignment
            ON resource.id = assignment.resource_id 
            AND assignment.enddate < now()
        LEFT JOIN project 
            ON project.id = assignment.project_id 
        LEFT JOIN role 
            ON role.id = assignment.role_id;

大多数数据库支持行数功能。使用此函数,您可以通过以下方式处理此问题:

SELECT 
  resource.firstname, 
  resource.lastname, 
  resource.fte, 
  project.name as project_name, 
  role.name as role_name, 
  assignment.startdate, 
  assignment.enddate, 
  assignment.numberofdaysperweek
FROM 
  resource
LEFT JOIN (select a.*,
                  row_number() over (partition by resource_id order by enddate) as seqnum
           from assignment a
           where assignment.enddate < now()
          ) assignment
     ON resource.id = assignment.resource_id AND seqnum = 1
LEFT JOIN project ON project.id = assignment.project_id 
LEFT JOIN role ON role.id = assignment.role_id;

row_number函数为每个值的resource_id分区内的分配按resource_id分配一个序列号。然后对这些分配进行排序,以便具有最新enddate的分配按enddate获得1 order值。

大多数数据库都支持row_number函数。使用此函数,您可以通过以下方式处理此问题:

SELECT 
  resource.firstname, 
  resource.lastname, 
  resource.fte, 
  project.name as project_name, 
  role.name as role_name, 
  assignment.startdate, 
  assignment.enddate, 
  assignment.numberofdaysperweek
FROM 
  resource
LEFT JOIN (select a.*,
                  row_number() over (partition by resource_id order by enddate) as seqnum
           from assignment a
           where assignment.enddate < now()
          ) assignment
     ON resource.id = assignment.resource_id AND seqnum = 1
LEFT JOIN project ON project.id = assignment.project_id 
LEFT JOIN role ON role.id = assignment.role_id;

row_number(行编号)函数为每个值的资源id分区内的分配按资源id分配一个序列号。然后对这些分配进行排序,以便具有最新结束日期的分配按结束日期获得1个值。

如何定义最后一个分配?是否也基于结束日期?开始日期?没有提到其他专栏?同一个资源不可能有两个工作分配重叠,所以,最后一个enddate,最后一个startdate,是相同的。资源的最新分配条目也是相同的。如何定义上次分配?是否也基于结束日期?开始日期?没有提到其他专栏?同一个资源不可能有两个工作分配重叠,所以,最后一个enddate,最后一个startdate,是相同的。资源的最新分配条目也是相同的。使用select,我从pour la table«分配»第23行:resource.id=assignment.resource_id上的分配中得到:ERREUR:entrée manquante de la子句和as。。。转换为:错误:表赋值的FROM子句中缺少条目我拼错了子查询上的别名赋值。我已经改正了。我的错,我以为我已经全部检查过了。谢谢,它工作得很好:使用select,我从pour la table«assignment»第23行:assignment ON resource.id=assignment.resource_id和as中获得:ERREUR:entrée manquante de la子句。。。转换为:错误:表赋值的FROM子句中缺少条目我拼错了子查询上的别名赋值。我已经改正了。我的错,我以为我已经全部检查过了。谢谢,很好用: