我的SQL查询正在处理一个日期,但我希望开始日期到结束日期

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了我的SQL查询正在处理一个日期,但我希望开始日期到结束日期相关的知识,希望对你有一定的参考价值。

我正在使用SQL Server 2005

我有两张桌子:

CheckInOut

TR          BadgeNum    USERID      Dated                   Time                    CHECKTYPE
-------     ---------   ------    -----------------------  -----------------------  ----------
2337334     4           1         2018-04-01 00:00:00.000  2018-04-14 10:10:58.000      I
2337334     4           1         2018-04-01 00:00:00.000  2018-04-14 18:10:00.000      O
2337334     4           1         2018-04-02 00:00:00.000  2018-04-14 10:00:10.000      I
2337335     4           1         2018-04-02 00:00:00.000  2018-04-14 18:14:27.000      O
2337336     4           1         2018-04-03 00:00:00.000  2018-04-14 10:22:10.000      I
2337334     4           1         2018-04-03 00:00:00.000  2018-04-14 18:03:11.000      O
2337337     44          5         2018-04-01 00:00:00.000  2018-04-14 09:27:03.000      I
2337337     44          5         2018-04-01 00:00:00.000  2018-04-14 18:27:42.000      O
2337337     44          5         2018-04-02 00:00:00.000  2018-04-14 10:00:50.000      I
2337337     44          5         2018-04-02 00:00:00.000  2018-04-14 18:02:25.000      O
2337337     44          5         2018-04-03 00:00:00.000  2018-04-14 08:58:36.000      I
2337337     44          5         2018-04-03 00:00:00.000  2018-04-14 18:12:18.000      O

用户信息

Tr     UserID    BadgeNumber     Name      
-----  -------   -----------  --------------
13652     44          5        SAMIA NAZ
13653     4           1        Waqar Yousufzai

我需要为每个用户计算每天的存在时间。我的下面的查询在给定的一天工作正常。但我需要计算给定的范围。我如何得到预期的结果?

Select  isnull(max(ch.userid), 0)As 'ID' 
    ,isnull(max(ch.badgenum), 0)as 'Badge#' 
    ,isnull(max(convert(Char(10), ch.dated, 103)), '00:00')as 'Date'
    ,isnull(max(ui.name),'Empty')as 'Name'
    ,isnull(min(convert(VARCHAR(26), ch.time, 108)), '00:00')   as 'Time In'
    ,case when min(ch.time) = max(ch.time) then '' else isnull(max(convert(VARCHAR(26), ch.time, 108)), '00:00') end as 'TimeOut' 
    ,case when min(ch.time) = max(ch.time) then 'Absent' else 'Present' end as 'Status' 
    ,isnull(CONVERT(varchar(3),DATEDIFF(minute,min(ch.time), max(ch.time))/60) + ' hrs and ' +
           RIGHT('0' + CONVERT(varchar(2),DATEDIFF(minute,min(ch.time),max(ch.time))%60),2)  + 'Min'  , 0) as 'Total Hrs'
    From CHECKINOUT ch left Join userinfo ui on ch.badgenum = ui.badgenumber
    Where ch.Dated between '2018-04-01' and '2018-04-03' GROUP BY ch.badgenum

查询结果

ID      Badge#  Date       Name             Time In     TimeOut     Status  Total Hrs
---     ------  ---------- ---------------  --------    ---------- -------- -----------------
4       1       03/04/2018 Waqar Yousufzai  11:33:34    18:24:23    Present 30 hrs and 14Min
82      3       03/04/2018 TANVEER ANSARI   09:37:14    19:18:22    Present 32 hrs and 37Min
13      4       03/04/2018                  07:19:26    09:30:17    Present 21 hrs and 49Min
44      5       03/04/2018 SAMIA NAZ        08:53:15    18:25:21    Present 33 hrs and 24Min
28      7       03/04/2018 Anees Ahmad      08:34:57    22:00:38    Present 61 hrs and 25Min
46      8       03/04/2018 Shazia - OT      08:10:41    16:15:05    Present 32 hrs and 01Min

预期结果

ID      Badge#  Date       Name             Time In     TimeOut     Status  Total Hrs
    ---     ------  ---------- ---------------  --------    ---------- -------- -----------------
    4       1       01/04/2018 Waqar Yousufzai  10:30:00    18:00:00    Present 7 hrs and 30Min
    4       1       02/04/2018 Waqar Yousufzai  10:30:00    18:00:00    Present 7 hrs and 30Min
    4       1       03/04/2018 Waqar Yousufzai  10:00:00    18:00:00    Present 8 hrs and 00Min
    44      5       01/04/2018 SAMIA            08:00:00    18:00:00    Present 10 hrs and 00Min
    44      5       02/04/2018 SAMIA            08:30:00    18:00:00    Present 9 hrs and 30Min
    44      5       03/04/2018 SAMIA            08:00:00    18:00:00    Present 10 hrs and 00Min
答案

您不应该对日期值进行聚合,它必须是分组的一部分。使用条件聚合获得时间和时间。并统计工作总时数。您的查询应该是这样的:

select
    BadgeNum, USERID, Dated, Name
    , right('0' + cast(datediff(mi, [in], [out]) / 60 as varchar(10)), 2) + ':'
    + right('0' + cast(datediff(mi, [in], [out]) % 60 as varchar(10)), 2)
from (
    select
        ch.BadgeNum, ch.USERID, dated = cast(ch.Dated as date), ui.Name
        , [in] = min(case when ch.CHECKTYPE = 'I' then ch.Time end)
        , [out] = min(case when ch.CHECKTYPE = 'O' then ch.Time end)

    from
        CheckInOut ch
        left join UserInfo ui on ch.USERID = ui.badgenumber
    where
        ch.Dated >= '20180401'
        and ch.Dated < '20180404'
    group by ch.BadgeNum, ch.USERID, cast(ch.Dated as date), ui.Name
) t

以上是关于我的SQL查询正在处理一个日期,但我希望开始日期到结束日期的主要内容,如果未能解决你的问题,请参考以下文章

(My)SQL:如果子查询不是空集,则返回子查询

根据条件在Access的SQL查询中创建日期字段

sql语句 时间段查询 高分

SQL 查询日期范围保存在 2 列中

在 SQL 中为给定年份设置硬编码的日期和月份

如何在 TCC 中导出最新的优惠开始日期