0

次のテーブルがあります-

Resource
--------------------
Id, ProjectId, Hours, ApproverId

Project
--------------------
Id, Name

入力は ApproverId です。一致する ApproverId を持つすべての行を取得する必要があります (簡単です)。また、返されたすべてのリソースについて、渡された承認者 ID ではない時間 (同じテーブル) も取得する必要があります (ビジネス要件、UI でグレー表示される必要があります)。私が今行っていることは、ApproverId に基づいてすべてのリソースを取得し、それらを一時テーブルに保存してから、Resource.Id を個別に実行し、別の一時テーブルに保存してから、すべての Resource.Id について、 ApproverId が渡されたものではない行。一時テーブルを使用する代わりに、すべてを単一のクエリに結合できますか?

ありがとう!

編集: SQL Server 2008 R2 を使用しています。

編集 2: これが私のストアド プロシージャです。コメントを読んだ後、ロジックを少し変更しました。すべての一時テーブルを削除して高速化することはできますか?

ALTER PROCEDURE GetResourceDataByApprover
    @ApproverId UNIQUEIDENTIFIER    
AS 
    CREATE TABLE #Table1
        (
          Id SMALLINT PRIMARY KEY
                      IDENTITY(1, 1) ,
          ResourceId UNIQUEIDENTIFIER
        )        

    CREATE TABLE #Table2
        (
          ResourceId UNIQUEIDENTIFIER ,
          ProjectId UNIQUEIDENTIFIER ,
          ProjectName NVARCHAR(1024)          
        )

    INSERT  INTO #Table1
            SELECT DISTINCT
                    ResourceId
            FROM    dbo.Resource T
            WHERE   T.ApproverId = @ApproverId


    DECLARE @i INT 
    DECLARE @numrows INT
    DECLARE @resourceId UNIQUEIDENTIFIER

    SET @i = 1 
    SET @numrows = ( SELECT COUNT(*)
                     FROM   #Table1
                   )

    IF @numrows > 0 
        WHILE ( @i <= ( SELECT  MAX(Id)
                        FROM    #Table1
                      ) ) 
            BEGIN 
                SET @resourceId = ( SELECT  ResourceId
                                    FROM    #Table1
                                    WHERE   Id = @i
                                  )


                INSERT  INTO #Table2
                        SELECT 
                                T.ResourceId ,
                                T.ProjectId ,
                                P.Name AS ProjectName

                        FROM    dbo.[Resource] T
                                INNER JOIN dbo.Project P ON T.ProjectId = P.ProjectId                                
                        WHERE   T.ResourceId = @resourceId                               


                SET @i = @i + 1 
            END

    SELECT  *
    FROM    #Table1 
    SELECT  *
    FROM    #Table2

    DROP TABLE #Table1  
    DROP TABLE #Table2
4

2 に答える 2

1

このクエリは、リソースごとに2つの行を返す必要があります。1つは指定された承認者用で、もう1つは他のすべての承認者用です。

SELECT 
  Id, 
  CASE
    WHEN ApproverId=@approverId THEN 'SpecifiedApprover'
    ELSE 'OtherApprover'
  END AS Approver, 
  SUM(Hours) AS Hours
FROM Resource
GROUP BY 
  Id,
  CASE
    WHEN ApproverId=@approverId THEN 'SpecifiedApprover'
    ELSE 'OtherApprover'
   END
于 2012-04-20T17:05:17.857 に答える
0

具体的な承認者がどのように時間を無駄にしているか知りたいですか?

SELECT p.Id, p.Name, SUM(r.Hours) as TotalHours
FROM Resource r
LEFT JOIN Project p
ON r.ProjectId = p.Id
WHERE ApproverId = %ConcreteApproverId%
GROUP BY p.Id, p.Name
HAVING SUM(r.Hours) > 0

このクエリは、次の表の例を生成します。

+-----+----------+-------+
| Id  | Project  | Hours |
+-----+----------+-------+
| 203 | ProjectA | 25    |
| 202 | ProjectB | 34    |
| 200 | ProjectC | 46    |
+-----+----------+-------+
于 2012-04-20T17:10:12.730 に答える