2016-12-23 23 views
0

嗨,我有(列(ID,開始時間,結束時間,USER_ID,CLIENT_ID,PROJECT_ID,TASK_ID,TotalHours)最好的方式獲得複雜的SQL數據(性能問題)

我需要輸出具有列客戶有timeLogs表,項目,任務,NoOfResources,TOTALTIME)與projectids,TaskID的,datefrom,datetill濾波器輸出樣本和表結構如下所示

enter image description here

這裏USER_ID,CLIENT_ID,TASK_ID,PROJECT_ID與用戶,客戶端外鍵,任務,項目

這裏#資源是用戶數量

我做它通過一個存儲過程:

ALTER procedure [dbo].[GetProjectUtilizationReport] 
    (@DateFrom datetime =null, 
    @DateTill datetime = null, 
    @TaskTypeIds nvarchar(max) = null, 
    @TaskIds nvarchar(max) = null, 
    @UserIds nvarchar(max) = null, 
    @ProjectIds nvarchar(max) = null) 
AS 
BEGIN 
    CREATE TABLE #TempTable(id int, 
          ProjectId int, 
          ClientId int, 
          UserId int, 
          TaskId int, 
          TotalHours numeric(18,2), 
          StartTime datetime, 
          TaskTypeId int) 

    --- create a temp table with data dump 
    INSERT INTO #TempTable(Id, ProjectId, ClientId, UserId, TaskId, TotalHours, StartTime, TaskTypeId) 
     SELECT 
      tl.id,Project_Id, Client_Id, 
      User_Id, Task_Id, TotalHours, 
      StartTime, TaskType_Id 
     FROM 
      TimeLogs tl 
     JOIN 
      Tasks t ON tl.Task_Id = t.Id 

    --apply filter to temp table 
    IF (@DateFrom IS NOT NULL) 
     DELETE FROM #TempTable 
     WHERE StartTime < @DateFrom 

    IF (@DateTill IS NOT NULL) 
     DELETE FROM #TempTable 
     WHERE StartTime > @DateTill 

    IF (@TaskTypeIds IS NOT NULL) 
     DELETE FROM #TempTable 
     WHERE TaskTypeId NOT IN (SELECT Item FROM dbo.SplitString(@TaskTypeIds, ',')) 

    IF (@TaskIds IS NOT NULL) 
     DELETE FROM #TempTable 
     WHERE TaskId NOT IN (SELECT Item FROM dbo.SplitString(@TaskIds, ',')) 

    IF (@UserIds IS NOT NULL) 
     DELETE FROM #TempTable 
     WHERE UserId NOT IN (SELECT Item FROM dbo.SplitString(@UserIds, ',')) 

    IF (@ProjectIds IS NOT NULL) 
     DELETE FROM #TempTable 
     WHERE ProjectId NOT IN (SELECT Item FROM dbo.SplitString(@ProjectIds, ',')) 

    --finaly select data 
    SELECT 
     p.Name as Project, c.Name as Client, 
     tl.TaskId, t.Name as Task, 
     SUM(TotalHours) as Totalhours, 
     COUNT(DISTINCT tl.UserId) as NoOfResources, 
     c.Id as ClientId 
    FROM 
     #TempTable tl 
    JOIN 
     Tasks t ON tl.TaskId = t.Id 
    JOIN 
     Clients c ON c.Id = tl.ClientId 
    JOIN 
     Projects p ON tl.ProjectId = p.Id 
    GROUP BY 
     tl.TaskId, c.id, c.Name, p.Name, t.Name 

    --drop temp table 
    DROP TABLE #TempTable 
END 

我認爲有可能是一個更好的方式 - 類似的看法等,但我沒有有任何想法嗎。

五月數據放在其他表上插入等

請把您的建議表明,我可以得到的結果一樣快,更多鈔票。

+0

您提供預期的結果。但沒有樣本數據。 – Viki888

+0

嗨,我已經連接不同的屏幕截圖也列有_被 – jitender

+0

你能相信的人等提供的解決方案,你沒有適當的樣本數據外鍵?我們不知道諾基亞在您的表格數據中屬於哪個'Client_Id'。同時提供樣本數據作爲文本而不是圖片,因爲我們很容易準備樣本數據並嘗試爲您解決問題。 – Viki888

回答

2

我常常儘量避免#tables在那裏我可以。

SELECT c.Name AS Client, p.Name AS Project, t.Name AS Task, COUNT(DISTINCT tl.User_Id) AS NoOfResources, SUM(TotalHours) AS Totalhours   
FROM TimeLogs tl 
INNER JOIN Tasks t ON tl.Task_Id =t.Id 
INNER JOIN Clients c ON c.Id =tl.Client_Id 
INNER JOIN Projects p ON tl.Project_Id =p.Id 
INNER JOIN (SELECT Item FROM dbo.SplitString(ISNULL(@UserIds, ''), ',')) users ON users.Item = tl.User_Id OR @UserIds IS NULL 
INNER JOIN (SELECT Item FROM dbo.SplitString(ISNULL(@TaskTypeIds, ''), ',')) tasktypes ON tasktypes.Item = tl.TaskType_Id OR @TaskTypeIds IS NULL 
INNER JOIN (SELECT Item FROM dbo.SplitString(ISNULL(@TaskIds, ''), ',')) tasks ON tasks.Item = tl.Task_Id OR @TaskIds IS NULL 
INNER JOIN (SELECT Item FROM dbo.SplitString(ISNULL(@ProjectIds, ''), ',')) projects ON projects.Item = tl.Project_Id OR @ProjectIds IS NULL 
WHERE (@DateFrom IS NULL OR StartTime < @DateFrom) 
AND (@DateTill IS NULL OR StartTime > @DateTill) 
GROUP BY c.Id, c.Name, p,Id, p.Name, t.Id, t.Name 
+0

感謝@Stephen的作品其實很多偉大的麪糊,然後我,但有關性能在大型數據的情況下,什麼假設百萬記錄在表 – jitender

+0

@jitender可以測試它。但我發現,#tables是資源密集型 – Stephen

+0

是的,我同意你在這種情況下,但我不能在SQL那麼強烈,我仍然認爲可能會有一些麪糊高性能的解決方案 – jitender