SQL Server员工入/出时钟时间重新格式化?
我对SQL比较陌生,已经写了很多不同的视图 我被要求使用SQL Server的时钟为我们的每月工资创建一份报告 目前,SQL格式:SQL Server员工入/出时钟时间重新格式化?,sql,sql-server,optimization,sql-server-2014,Sql,Sql Server,Optimization,Sql Server 2014,我对SQL比较陌生,已经写了很多不同的视图 我被要求使用SQL Server的时钟为我们的每月工资创建一份报告 目前,SQL格式: Date | Name | Clock In | Clock Out -----------+------+-------------------------+------------------------ 01/02/2018 | Name | 2018-02-01 07:55:08.563 | 2018-02-01 1
Date | Name | Clock In | Clock Out
-----------+------+-------------------------+------------------------
01/02/2018 | Name | 2018-02-01 07:55:08.563 | 2018-02-01 10:21:42.183
01/02/2018 | Name | 2018-02-01 10:32:37.153 | 2018-02-01 13:12:33.773
01/02/2018 | Name | 2018-02-01 13:33:10.123 | 2018-02-01 15:04:16.880
但是我希望它是这样的:
Date | Name | Clock In | Clock Out | Clock In | Clock Out | Clock In | Clock Out
--
01/02/2018 | Name | 2018-02-01 07:55:08.563 | 2018-02-01 10:21:42.183 | 2018-02-01 10:32:37.153 | 2018-02-01 13:12:33.773 | 2018-02-01 13:33:10.123 | 2018-02-01 15:04:16.880
我目前在excel中使用以下公式:
{=INDEX(Payroll_Clockings[Start Time], SMALL(IF(1 = ((--($A9=Payroll_Clockings[Date Value])) * (--($J$4=Payroll_Clockings[Name]))), ROW(Payroll_Clockings[Start Time]) -1, ""), COLUMN() -1))}
但作为一个数组公式,当有50多条记录时,刷新可能需要很长时间
因此,通过SQL重新安排事物是理想的
我使用的SQL视图是:
SELECT TOP (100) PERCENT
CONVERT(VARCHAR(19), ShopFloor.EmployeeActivity.StartEvent, 103) AS Date,
Admin.Employee.FirstName + ' ' + Admin.Employee.Surname AS Name,
ShopFloor.EmployeeActivity.StartEvent AS [Start Time],
ShopFloor.EmployeeActivity.FinishEvent AS [Finish Time],
ShopFloor.EmployeeActivity.ClockNumber AS [Clock No.]
FROM
ShopFloor.EmployeeActivity
LEFT OUTER JOIN
Admin.Employee ON ShopFloor.EmployeeActivity.ClockNumber = Admin.Employee.ClockNumber
WHERE
(ShopFloor.EmployeeActivity.StartEvent BETWEEN GETDATE() - 180 AND GETDATE())
AND (NOT (ShopFloor.EmployeeActivity.ClockNumber IN (100, 10090, 10000, 777, 999, 10001, 10098, 10002)))
AND (ShopFloor.EmployeeActivity.ActivityTypeCode = 1)
ORDER BY
Date, Name, [Start Time]
希望这是有意义的,任何帮助都将被感激
看看这里: 这似乎是正确的想法,但他们只在5行上工作,我当前的数据大约是10000行。。。有办法解决这个问题吗 谢谢 编辑 根据以下丹尼尔的建议,我有以下几点:
`WITH CTE AS (SELECT CONVERT(VARCHAR(19), StartEvent, 103) AS Date,
StartEvent AS Start, FinishEvent AS Finish, ClockNumber AS Clock
FROM ShopFloor.EmployeeActivity
WHERE (StartEvent >= CONVERT(DATETIME, '2021-01-01 00:00:01', 102))
AND (NOT (ClockNumber IN (100))) AND (ActivityTypeCode = 1)
ORDER BY Date, Start)
select a.date, a.Clock, a.[1],b.[1],a.[2],b.[2],a.[3],b.[3] from (
select date, Clock, max([1])[1],max([2])[2],max([3])[3] from(
select *, row_number() over(partition by date, Clock order by date)b from
CTE) a
pivot(max(Start) for b in ([1],[2],[3]))c
group by date, Clock)a
left join
(
select date, Clock, max([1])[1],max([2])[2],max([3])[3] from(
select *, row_number() over(partition by date, Clock order by date)b from
CTE) a
pivot(max(Finish) for b in ([1],[2],[3]))c
group by date, Clock)
b on a.date=b.date and a.Clock=b.Clock `
如果您知道每个员工的最大登录/注销组合数,那么类似的方法就可以实现。否则,您将不得不使用动态sql来生成数据透视。尝试一下,让我知道它对您的作用:
select a.date, a.name, a.[1],b.[1],a.[2],b.[2],a.[3],b.[3] from (
select date, name, max([1])[1],max([2])[2],max([3])[3] from(
select *, row_number() over(partition by date, name order by date)b from #temp) a
pivot(max(clockin) for b in ([1],[2],[3]))c
group by date, name)a
left join
(
select date, name, max([1])[1],max([2])[2],max([3])[3] from(
select *, row_number() over(partition by date, name order by date)b from #temp) a
pivot(max(clockout) for b in ([1],[2],[3]))c
group by date, name)
b on a.date=b.date and a.name=b.name
不要在数据引擎中这样做,而是在表示层中旋转数据。特别是考虑到您希望所有列具有相同的名称(不理想);我会看看Pivot,看看我能想出什么。如果是你,你会建议如何解决这个问题?正如@Larnu所说的,不要在数据库中这样做。它不是为可变列数而设计的;每个员工每天有3个入职和离职。除此之外的任何事项将由人力资源部确定/执行。我现在要试试你的建议:)太好了,让我知道它是怎么回事,教授,我想我把自己搞糊涂了/可能有点超出我的深度了?-我已经尝试将我自己的信息替换到您的代码中,但是我对[1]、[2]和[3]所指的内容有点困惑?我试图简化事情,只使用Shopfool.EmployeeActivity表,因此我会有以下列:时钟号、StartEvent、FinishEvent、日期(从StartEvent转换而来)和ActivityTypeCode=1其中两三个是第一次登录、第一次注销、第二次登录、第二次注销等感谢您的帮助。最后我把事情留给了Excel,因为我认为我对SQL的了解还不够,无法继续使用您的方法。