I am relatively new to SQL and have written a bunch of various views.
I have been asked to created a report for our monthly payroll using clockings from SQL Server.
Currently SQL formats things:
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
However I would like it something like this:
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
I have things currently working in excel using the formula:
{=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))}
But being an Array formula this can take a long time to refresh when there are 50+ records.
So it would be ideal to rearrange things through SQL.
the SQL view i am using is:
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]
Hopefully this makes sense and any help would be appreciated!
After looking here: SQL Server - PIVOT - two columns into rows
This seems to be the right idea however they are only working on 5 rows, my current data is coming to around 10,000 rows... would there be a way around that?
Thanks
EDIT
Further to Daniel's suggestion below I have the following;
`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 `