0

私は、簡単な 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 つのテーブルがresourcesあります。そのプロジェクトに固有のテーブルが与えられassignedます。projectsrole

このクエリの問題は、任意のリソース + 「期限切れ」の割り当て (assignment.enddate < now()) を持つ任意のリソースのデータが返されることです。ただし、この条件は、そのリソースの最後の割り当てにのみ適用する必要があります。どうすればこれを達成できるか分かりますか?

4

2 に答える 2

1

割り当てを各リソースの最新の割り当てのみに制限するには、各 resource_id の最新の開始日を見つけてINNER 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;

これだけをしたいのでLEFT JOIN、上記LEFT JOINの全体をサブクエリに移動し、サブクエリ全体をメインクエリに戻す必要があります。

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;

リソースごとの「最後の」割り当ての解釈を誤解している場合は、サブクエリ内のアガゲートMaxAssignmenと への内部結合をいじる必要があるかもしれませんassignmentsが、同じプリンシパルが適用されます。

編集

何らかの理由でこれが MySQL であると想定していましたが、以下のコメントのエラー メッセージは Postgresql のように見えます。この場合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  *, ROW_NUMBER() OVER(PARTITION BY ResourceID ORDER BY StartDate DESC) RN
            FROM    assignment
        ) assignment
            ON resource.id = assignment.resource_id 
            AND RN = 1
            AND assignment.enddate < now()
        LEFT JOIN project 
            ON project.id = assignment.project_id 
        LEFT JOIN role 
            ON role.id = assignment.role_id;
于 2013-06-17T10:18:26.870 に答える