【问题标题】:Grouping multiple days together将多天组合在一起
【发布时间】:2015-11-11 17:29:15
【问题描述】:

我有一个查询,可以获取有关员工时钟时间的数据。此查询还添加了一个名为 inDay 的字段,按天对行进行分组并给它们一个数字。这样我就可以对行进行日期差异以获得正确的工作时间。

    SELECT     CHINA_VISION_PubPersonnel.Name, CHINA_VISION_PubPersonnel.ID, CHINA_VISION_PubCards.CardCode, CHINA_VISION_PubPersonnel.Telephone, ATDShiftDetail.EndOverDay, 
                          CHINA_VISION_DorEvents.EventTM AS T, CONVERT(VARCHAR(10), CHINA_VISION_DorEvents.EventTM, 102) AS Day, FLOOR(CONVERT(FLOAT, 
                          CHINA_VISION_DorEvents.EventTM)) AS DayNumber,    
                          ROW_NUMBER() OVER(PARTITION BY FLOOR(CONVERT(FLOAT,CHINA_VISION_DorEvents.EventTm)) ORDER BY CHINA_VISION_DorEvents.EventTm) InDay  
    FROM         CHINA_VISION_PubCards INNER JOIN
                          CHINA_VISION_PubPersonnel ON CHINA_VISION_PubCards.PubPersonnel_Ref = CHINA_VISION_PubPersonnel.Reference INNER JOIN
                          CHINA_VISION_DorEvents ON CHINA_VISION_PubCards.CardCode = CHINA_VISION_DorEvents.CardCode INNER JOIN
                          ATDShiftDetail ON RIGHT(CHINA_VISION_PubPersonnel.ID, 4) = ATDShiftDetail.Name
    WHERE     (CHINA_VISION_DorEvents.DorCtrls_Ref = '16') AND (CHINA_VISION_DorEvents.CardCode = '0042f55c') AND (CONVERT(Date, CHINA_VISION_DorEvents.EventTM) 
                          > DATEADD(day, - 6, GETDATE())) AND ATDShiftDetail.EndOverDay = '1'

示例输出数据。

        Name    ID  CardCode Telephone  EndOverDay          T                   Day   DayNumber InDay
        ----------------------------------------------------------------------------------------------
    Joe Blogs   1   0042f55c    8           1       2015-11-06 01:17:05.000 2015.11.06  42312   1
    Joe Blogs   1   0042f55c    8           1       2015-11-06 01:45:44.000 2015.11.06  42312   2
    Joe Blogs   1   0042f55c    8           1       2015-11-06 07:45:56.000 2015.11.06  42312   3
    Joe Blogs   1   0042f55c    8           1       2015-11-09 19:39:21.000 2015.11.09  42315   1
    Joe Blogs   1   0042f55c    8           1       2015-11-10 01:11:15.000 2015.11.10  42316   1
    Joe Blogs   1   0042f55c    8           1       2015-11-10 01:36:39.000 2015.11.10  42316   2
    Joe Blogs   1   0042f55c    8           1       2015-11-10 07:57:02.000 2015.11.10  42316   3
    Joe Blogs   1   0042f55c    8           1       2015-11-10 19:42:45.000 2015.11.10  42316   4
    Joe Blogs   1   0042f55c    8           1       2015-11-11 01:16:07.000 2015.11.11  42317   1
    Joe Blogs   1   0042f55c    8           1       2015-11-11 01:40:06.000 2015.11.11  42317   2
    Joe Blogs   1   0042f55c    8           1       2015-11-11 07:55:20.000 2015.11.11  42317   3

但是,这个员工晚上工作,这意味着我需要将前一天晚上的最后一条记录分组,这将是他们在接下来的三个记录中打卡的时候。

在这里使用上面的输出是输出应该是什么样的。

一旦数据是我喜欢的数据,我就可以对行进行日期差异以获取员工的工作时间。

        Name    ID  CardCode Telephone  EndOverDay          T                   Day   DayNumber InDay
        ----------------------------------------------------------------------------------------------
    Joe Blogs   1   0042f55c    8           1       2015-11-06 01:17:05.000 2015.11.06  42312   1 -- were missing the record from the night before so start at 1 here
    Joe Blogs   1   0042f55c    8           1       2015-11-06 01:45:44.000 2015.11.06  42312   2
    Joe Blogs   1   0042f55c    8           1       2015-11-06 07:45:56.000 2015.11.06  42312   3
    Joe Blogs   1   0042f55c    8           1       2015-11-09 19:39:21.000 2015.11.09  42315   1
    Joe Blogs   1   0042f55c    8           1       2015-11-10 01:11:15.000 2015.11.10  42316   2
    Joe Blogs   1   0042f55c    8           1       2015-11-10 01:36:39.000 2015.11.10  42316   3
    Joe Blogs   1   0042f55c    8           1       2015-11-10 07:57:02.000 2015.11.10  42316   4
    Joe Blogs   1   0042f55c    8           1       2015-11-10 19:42:45.000 2015.11.10  42316   1
    Joe Blogs   1   0042f55c    8           1       2015-11-11 01:16:07.000 2015.11.11  42317   2
    Joe Blogs   1   0042f55c    8           1       2015-11-11 01:40:06.000 2015.11.11  42317   3
    Joe Blogs   1   0042f55c    8           1       2015-11-11 07:55:20.000 2015.11.11  42317   4

【问题讨论】:

  • 您能否编辑您的示例以仅包含必要的详细信息并使其更具可读性?例如,表名的 CHINA_VISION_ 前缀使其难以阅读,您必须滚动才能查看查询。由于结果都具有相同的名称、ID 和 CardCode,因此这些详细信息与您的问题并不真正相关。如果您可以在sqlfiddle 上发布一个包含一些数据的示例,那就太好了。
  • 您好,“CHINA_VISION_”前缀是必需的,因为这里有多个表和示例数据。 Name 和 ID 都是一样的,我只是编辑了它以删除真实姓名,但是这些数据都属于同一个人,我编辑它看起来更像实际结果
  • 你有没有每个员工的工作时间(进出)的表格?
  • 如果您的问题更容易理解,您将有更多的人关注您的问题并提出答案。您发布的问题不必编译为数据库中的查询,使用长表名并包含与实际问题无关的数据将使很多人跳过这个问题。见"How to create a Minimal, Complete, and Verifiable example"
  • 图片如果你有刷卡,每次你进来工作你必须刷那张卡说你在这里,每次你离开你再刷一次。这就是 CHINA_VISION_DorEvents.EventTM AS T 的含义 所以 T 中的每条记录都是员工刷卡说他们进出的时候,

标签: sql sql-server


【解决方案1】:

您必须有某种方法来判断轮班何时开始和结束,还是只是“一天中的最后时间总是轮班的开始”?如果有特定的时间,如果他们总是在晚上 7:00 之后打卡,那么这种情况下很容易将时间更改 5 小时以获得日期数:

FLOOR(CONVERT(FLOAT, DATEADD(hour, 5, EventTM))) AS DayNumber

【讨论】:

  • 是的,谢谢,这是我想要的 DayNumber,然后我可以从中设置 InDay,谢谢
【解决方案2】:

这是一个功能性问题而不是技术性问题...如果日期可能不同,您如何知道哪个“进”和“出”属于一起?例如,前四个记录可能意味着 emp 在 6-11 1:17 来,6-11 1:45 离开,6-11 7:45 来,然后停留三天直到 9-11 19:39。

9-11 只有一个时间戳;应该如何处理?

您需要一个代码来判断 emp 时间戳是“输入”还是“输出”,这是确定时钟记录之间哪个时间跨度“存在”和哪个“不存在”的唯一方法。

【讨论】:

    猜你喜欢
    • 2013-04-05
    • 1970-01-01
    • 2021-12-09
    • 2018-02-18
    • 2022-10-08
    • 1970-01-01
    • 2017-04-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多