SQL Optimize查询方式

时间:2014-10-24 07:44:31

标签: sql sql-server sql-server-2005

我有一个带INNER JOIN的SQL查询SUB Query。我使用Aggregate Function(MIN & MAX)Group By。在我的子查询中,我计算日期&时间差异,我将其命名为TotalTime列。我的问题是,当检索到2个或更多记录时,它将计算我输入的日期范围内的整个date_request。(请参阅下面的示例查询代码

这是我的疑问:

SELECT tblOT_Details.userid,(tblUsers.firstname + ' ' +tblUsers.lastname) AS name,
tblOT_Details.task,tblOT_Details.date_request,
MIN(tblOT_Details.time_from) AS time_from,MAX(tblOT_Details.time_to) AS time_to,
totaltime = (select datediff(HOUR,0,ET-ST) + cast(datediff(MI,0,ET-ST) - (datediff(HOUR,0,ET-ST) * 60) As Decimal) / 100 
           from
           (
            select
                ST=convert(datetime,MIN(tblOT_Details.time_from)),
                ET=convert(datetime,MAX(tblOT_Details.time_to)) from tblOT_Details
                  WHERE userid IN ('USER1','USER2','USER3')
                  AND date_request BETWEEN '09/01/2014' AND '10/25/2014' ---> I know here is the problem. Should I use Looping Here to get the specific totalhours per user? 
            ) a 
        ),
tblOT.Approved_by
FROM tblOT_Details
INNER JOIN tblOT
ON tblOT_Details.userid = tblOT.requested_by
AND CONVERT(varchar,tblOT_Details.date_request,101) = CONVERT(varchar,tblOT.date_request,101)
INNER JOIN tblUsers
ON tblOT_Details.userid = tblUsers.User_Id
WHERE tblOT_Details.userid IN ('USER1','USER2','USER3')
AND tblOT.status='Approved'
AND tblOT_Details.totaltime IS NOT NULL
AND tblOT_Details.date_request BETWEEN '09/01/2014' AND '10/25/2014'
GROUP BY tblOT_Details.userid,(tblUsers.firstname + ' ' +tblUsers.lastname),tblOT_Details.task,tblOT_Details.date_request,tblOT.Approved_by
ORDER BY tblOT_Details.date_request ASC

这是我的样本查询表:

enter image description here

PROOF THAT IT CALCULATES THROUGHOUT DATE RANGE

正如您在列名TotalTime中看到的那样,它们都是相同的数字,因为它会计算我在BETWEEN函数中输入的日期范围。我的问题是,我应该在每个日期范围内使用循环来获得每个用户的特定min&max date吗?或者你有一些优化/更好的方法来做到这一点?

2 个答案:

答案 0 :(得分:1)

您可以删除子查询,您的查询就像

select col1,col2,'aaa' from tablename

这适用于每个用户

SELECT tblOT_Details.userid,
       ( tblUsers.firstname + ' ' + tblUsers.lastname )                                                                                                                                                                                                                                                                                                                                           AS NAME,
       tblOT_Details.task,
       tblOT_Details.date_request,
       Min(tblOT_Details.time_from)                                                                                                                                                                                                                                                                                                                                                               AS time_from,
       Max(tblOT_Details.time_to)                                                                                                                                                                                                                                                                                                                                                                 AS time_to,
       Datediff(HOUR, 0, CONVERT(DATETIME, Max(tblOT_Details.time_to)) - CONVERT(DATETIME, Min(tblOT_Details.time_from))) + Cast(Datediff(MI, 0, CONVERT(DATETIME, Max(tblOT_Details.time_to)) - CONVERT(DATETIME, Min(tblOT_Details.time_from))) - ( Datediff(HOUR, 0, CONVERT(DATETIME, Max(tblOT_Details.time_to)) - CONVERT(DATETIME, Min(tblOT_Details.time_from))) * 60 ) AS DECIMAL) / 100 tblOT.Approved_by
FROM   tblOT_Details
       INNER JOIN tblOT
               ON tblOT_Details.userid = tblOT.requested_by
                  AND CONVERT(VARCHAR, tblOT_Details.date_request, 101) = CONVERT(VARCHAR, tblOT.date_request, 101)
       INNER JOIN tblUsers
               ON tblOT_Details.userid = tblUsers.User_Id
WHERE  tblOT_Details.userid IN ( 'USER1', 'USER2', 'USER3' )
       AND tblOT.status = 'Approved'
       AND tblOT_Details.totaltime IS NOT NULL
       AND tblOT_Details.date_request BETWEEN '09/01/2014' AND '10/25/2014'
GROUP  BY tblOT_Details.userid,
          ( tblUsers.firstname + ' ' + tblUsers.lastname ),
          tblOT_Details.task,
          tblOT_Details.date_request,
          tblOT.Approved_by
ORDER  BY tblOT_Details.date_request ASC 

答案 1 :(得分:1)

学习CTE:

;WITH cte_ot AS (
SELECT UserID, date_request, SUM(     DATEDIFF(HOUR, 0, time_to - time_from) + CAST(DATEDIFF(MI, 0, time_to - time_from) - DATEDIFF(HOUR, 0, time_to - time_from) * 60 AS Decimal) / 100) as TotalTime
FROM         tblOT_Details
GROUP BY UserID, date_request
)

select UserID, date_request, TotalTime
from cte
--add join here