【问题标题】:My SQL Query is working on one date, but I want start date to end date我的 SQL 查询正在处理一个日期,但我希望从开始日期到结束日期
【发布时间】:2018-09-30 21:58:55
【问题描述】:

我使用的是 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

【问题讨论】:

  • group byselect中列出ch.Dated
  • 编辑您的问题,以便您的示例和描述中的值与您的查询实际匹配。然后给出示例输入和输出数据。然后取出不相关的代码,专注于你试图探索的问题的最小部分。 stackoverflow.com/help/mcve
  • 所以不是每个批次编号一个结果行,而是每个批次编号和日期一个结果行?
  • 我已经在尝试 'group by ch.Dated ' 但它返回了一些员工..
  • 我想要多行按日期排列的徽章... ID 徽章# 日期 姓名 进入时间 超时 112 127 01/04/2018 Zafar 07:15 22:59 112 127 02/04/2018 Zafar 07:00 23:00 112 127 01 /04/2018 玫瑰 08:00 16:00 112 127 02/04/2018 玫瑰 08:30 16:10 等

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


【解决方案1】:

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

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

【讨论】:

  • 谢谢您,先生....有一些问题。您在示例中使用 Checktype 列,但我不想使用 CheckType 列。我想花时间使用 Min() 作为 'In' 和 Max() 作为 'Out' 运算符。和显示列 Time In 和 Time Out。
  • 如果没有 CheckType 列,您无法确定您获得的日期。例如,对于一天只有一个条目的用户,minmax 函数将返回相同的值。你怎么知道那是InOut?但是如果你想按你说的做,只需根据需要更改聚合函数
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-11-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多