识别时差不足的行SQL Server 2008 R2

时间:2014-04-11 11:01:20

标签: sql-server date sql-server-2008-r2

我已在网站上审核并尝试了大量代码示例,但我没有更接近解决我的问题。我认为部分原因在于我的编码技巧,部分原因是SQL Server 2008R2缺少LAG。

我的表Clock__Times包含数万行这些列:

EMP_NO, ACCOUNT_DATE, IN_STAMP, OUT_STAMP

发生时钟输出活动时会添加一行。每天可以为给定员工添加多行。我需要在时钟输出时间(ACCOUNT_DATE BETWEEN D1 & D2)和下一个时钟(OUT_STAMP之间的时间内识别行并计算员工在给定时间跨度(IN_STAMP)内的时间。 )该员工少于X小时但大于Y小时。

我尝试了各种JOIN但它们总是错误的,因为我必须将同一行的OUT_STAMP与为同一员工添加的下一行的IN_STAMP进行比较。

Y值是为了避免午餐时钟进出活动,并且可能有2小时的值。 X值用于识别在轮班之间没有足够时间的员工,例如10小时。

我最终必须扩大规模,以确定在一段时间内没有足够休假的所有员工。

1 个答案:

答案 0 :(得分:1)

好的,这是一个潜在解决方案的试验。

标准:

  • 您的表格中有时钟输入和时钟输出作为日期时间
  • 表中有多名员工
  • 您想要查找所有出现的时钟输出,然后是时钟输入(对于同一员工)
    • 差异大于2小时
    • 差异小于10小时

这是一个完整的SQL示例,它创建了一个包含数据和最后查询的示例表:

IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'SO23010761')
    DROP TABLE SO23010761
GO

CREATE TABLE SO23010761
(
    emp     INT,
    dt      DATETIME,
    type    CHAR(1)
)
GO

INSERT INTO SO23010761
VALUES
    (1, '2014-01-01 08:00', 'I'),
    (1, '2014-01-01 08:15', 'O'),
    (1, '2014-01-01 10:30', 'I'),
    (1, '2014-01-01 16:00', 'O'),
    (2, '2014-01-01 08:00', 'I'),
    (2, '2014-01-01 08:15', 'O'),
    (2, '2014-01-01 10:30', 'I'),
    (2, '2014-01-01 16:00', 'O')
GO

WITH meta
AS (
    SELECT
        *,
        ROW_NUMBER() OVER (PARTITION BY emp ORDER BY dt) AS ROWNUM
    FROM
        SO23010761
)
SELECT
    *
FROM
    (
        SELECT
            M1.emp,
            M1.dt AS dt_out,
            M2.dt AS dt_in,
            DATEDIFF(MI, M1.dt, M2.dt) AS DIFF
        FROM
            meta M1
            INNER JOIN meta M2
                ON M1.emp = M2.emp
                AND M1.rownum = M2.rownum - 1
        WHERE
            M1.type = 'O'
        AND M2.type = 'I'
    ) AS dummy
WHERE
    DIFF >= 2 * 60
AND DIFF <= 10 * 60
GO

这将:

  • 创建一个元表,按顺序为单个员工编号每行
  • 为同一名员工加入1行与下一行(即1个更高的行号)。基本上,如果员工的行是行A,B,C,D(按此顺序),您将加入A与B,B与C,C与D
  • 过滤以便我们只包含这样的匹配,其中我们有一个OUT后跟一个IN
  • 以分钟为单位计算OUT和IN之间的差异
  • 选择差异较大(或在本例中等于)2小时但小于10的行。