我有一个带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
这是我的样本查询表:
PROOF THAT IT CALCULATES THROUGHOUT DATE RANGE
正如您在列名TotalTime
中看到的那样,它们都是相同的数字,因为它会计算我在BETWEEN
函数中输入的日期范围。我的问题是,我应该在每个日期范围内使用循环来获得每个用户的特定min&max date
吗?或者你有一些优化/更好的方法来做到这一点?
答案 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