需要另一种方法,也许是转向?

问题描述 投票:0回答:1

大家需要你的想法。

我像这样登录和注销。

DECLARE @t TABLE( id INT IDENTITY(1, 1), empid VARCHAR(10), logindate DATE, logintime TIME, logoutdate DATE, logouttime TIME)
INSERT @t (empid, logindate, logintime, logoutdate, logouttime) VALUES('251803', CAST(N'2024-06-28T00:00:00.000' AS DATETIME), CAST(N'1899-12-30T08:00:00.000' AS TIME), CAST(N'2024-06-28T00:00:00.000' AS DATETIME), CAST(N'1899-12-30T11:00:00.000' AS TIME))
INSERT @t (empid, logindate, logintime, logoutdate, logouttime) VALUES ('251803', CAST(N'2024-06-28T00:00:00.000' AS DATETIME), CAST(N'1899-12-30T12:00:00.000' AS TIME), CAST(N'2024-06-28T00:00:00.000' AS DATETIME), CAST(N'1899-12-30T16:59:00.003' AS TIME))
INSERT @t (empid, logindate, logintime, logoutdate, logouttime) VALUES ('251809', CAST(N'2024-06-28T00:00:00.000' AS DATETIME), CAST(N'1899-12-30T08:00:00.000' AS TIME), CAST(N'2024-06-28T00:00:00.000' AS DATETIME), CAST(N'1899-12-30T10:14:00.003' AS TIME))
INSERT @t (empid, logindate, logintime, logoutdate, logouttime) VALUES ('251809', CAST(N'2024-06-28T00:00:00.000' AS DATETIME), CAST(N'1899-12-30T11:13:00.000' AS TIME), CAST(N'2024-06-28T00:00:00.000' AS DATETIME), CAST(N'1899-12-30T17:20:00.003' AS TIME))
INSERT @t (empid, logindate, logintime, logoutdate, logouttime) VALUES ('251800', CAST(N'2024-06-28T00:00:00.000' AS DATETIME), CAST(N'1899-12-30T08:00:00.000' AS TIME), CAST(N'2024-06-28T00:00:00.000' AS DATETIME), CAST(N'1899-12-30T13:08:00.003' AS TIME))
INSERT @t (empid, logindate, logintime, logoutdate, logouttime) VALUES('251800', CAST(N'2024-06-28T00:00:00.000' AS DATETIME), CAST(N'1899-12-30T14:08:00.003' AS TIME), CAST(N'2024-06-28T00:00:00.000' AS DATETIME), CAST(N'1899-12-30T17:00:00.003' AS TIME))
INSERT @t (empid, logindate, logintime, logoutdate, logouttime) VALUES ('251800', CAST(N'2024-06-28T00:00:00.000' AS DATETIME), CAST(N'1899-12-30T18:00:00.003' AS TIME), CAST(N'2024-06-28T00:00:00.000' AS DATETIME), CAST(N'1899-12-30T18:00:00.003' AS TIME))
INSERT @t (empid, logindate, logintime, logoutdate, logouttime) VALUES('251800', CAST(N'2024-06-28T00:00:00.000' AS DATETIME), CAST(N'1899-12-30T20:08:00.003' AS TIME), CAST(N'2024-06-28T00:00:00.000' AS DATETIME), CAST(N'1899-12-30T21:00:00.003' AS TIME))

我需要这样输出。

enter image description here

我做了一些脚本

DECLARE @clock TABLE (i INT IDENTITY, empid VARCHAR(10), datetimelog DATETIME, log_status VARCHAR(10), punch VARCHAR(10))
DECLARE @i INT = 1, @pnum INT, @curempid VARCHAR(10)
DECLARE @empid VARCHAR(10), @logindate DATE, @logintime TIME, @logoutdate DATE, @logouttime TIME

WHILE (@i <= (SELECT MAX(id)FROM @t))
    BEGIN
        SELECT @empid = empid, @logindate = logindate, @logintime = logintime, @logoutdate = logoutdate, @logouttime = logouttime
        FROM @t WHERE id = @i ORDER BY empid, logindate

        
        IF (@curempid IS NULL)
            BEGIN
                SET @curempid = @empid
                SET @pnum = 1
            END
        ELSE
            BEGIN
                IF (@curempid = @empid)
                    BEGIN
                        SET @pnum = @pnum + 1
                    END
                ELSE
                    BEGIN
                        SET @curempid = @empid
                        SET @pnum = 1
                    END
            END

        INSERT INTO @clock (empid, datetimelog, log_status, punch)
        VALUES (@empid, CAST(@logindate AS DATETIME) + CAST(CAST(@logintime AS TIME) AS DATETIME), 'IN', @pnum)
        
        SET @pnum = @pnum + 1
        
        INSERT INTO @clock (empid, datetimelog, log_status, punch)
        VALUES (@empid, CAST(@logoutdate AS DATETIME) + CAST(CAST(@logouttime AS TIME) AS DATETIME), 'OUT', @pnum)

        SET @i = @i + 1;
    END;

有更好的方法吗? 我认为是枢轴,但我不知道枢轴方式。 需要你的专业知识。 预先感谢

谢谢。

sql pivot transform
1个回答
0
投票

您可以合并来自同一个表的两个结果集,然后使用窗口函数添加

ROW_NUMBER()
来实现此目的。

由于您没有提及您的 RDBMS,因此我没有将您的日期和时间戳合并在一起,因为这将特定于平台。另外,如果你使用的是不支持窗口函数的旧版本 mysql,则需要更改此逻辑。

SELECT empid,
    datelog,
    timelog,
    log_status,
    ROW_NUMBER() OVER (PARTITION BY empid ORDER BY datelog, timelod) as punch
FROM 
  (
    SELECT empid, 
        logindate as datelog, 
        logintime as timelog, 
        CAST('IN' as VARCHAR(10)) as log_status,
    FROM @t 
    UNION ALL
    SELECT empid, 
        logoutdate,
        logouttime, 
        'OUT',
    FROM @t 
  )dt 
ORDER BY empid, datelog, timelog
© www.soinside.com 2019 - 2024. All rights reserved.