У меня вход и выход такой.
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))
Мне нужно вывести это так:
Я написал этот SQL-скрипт
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;
Есть ли лучший способ сделать это? Я думаю о повороте, но я не знаю способа поворота. заранее спасибо
mssql брат..
Вы можете просто объединить два набора результатов, созданных из одной таблицы, а затем добавить ROW_NUMBER()
, используя оконную функцию, чтобы добиться этого.
Поскольку вы не упомянули свою СУБД, я не объединил вашу дату и отметку времени, поскольку это будет зависеть от платформы. Кроме того, если вы используете более старую версию 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
Поскольку вы используете SQL Server, вы можете использовать CROSS APPLY ... VALUES
, чтобы разделить каждую исходную строку на две выходные строки. БД Скрипка
WITH T AS
(
SELECT
2 * ROW_NUMBER() OVER (PARTITION BY empid ORDER BY id)-1 AS punch_base,
2 * ROW_NUMBER() OVER (ORDER BY id)-1 AS i_base,
*
FROM @t
)
SELECT i = i_base + base_offset,
empid,
datelog,
timelog,
log_status,
punch = punch_base + base_offset
FROM T
CROSS APPLY (VALUES
(logindate, logintime, 'IN', 0),
(logoutdate, logouttime, 'OUT', 1)
)V(datelog, timelog, log_status, base_offset)
Какие СУБД вы используете? (Приведенный выше код зависит от продукта.)