У меня есть такая структура таблиц, которая ежедневно посещает сотрудников магазина. Я хочу получить результат, чтобы я мог узнать под датой, сколько раз сотрудник отмечал посещаемость, если он регистрировался, он давал какой-либо статус, скажем, IN, а если это был заказ, он говорил бы OUT в отдельной колонке.
/****** Object: Table [dbo].[Attendance] Script Date: 4/24/2019 2:22:47 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Attendance](
[EmpCode] [int] NULL,
[TimeIn] [datetime] NULL,
[TimeOut] [datetime] NULL
) ON [PRIMARY]
GO
/****** Object: Table [dbo].[Employee] Script Date: 4/24/2019 2:22:47 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Employee](
[ID] [int] NOT NULL,
[EmployeeName] [varchar](25) NULL,
[Department] [varchar](25) NULL,
[CenterCode] [int] NULL,
CONSTRAINT [PK_Employee] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
INSERT [dbo].[Attendance] ([EmpCode], [TimeIn], [TimeOut]) VALUES (1, CAST(N'2019-02-01 06:30:00.000' AS DateTime), NULL)
GO
INSERT [dbo].[Attendance] ([EmpCode], [TimeIn], [TimeOut]) VALUES (1, NULL, CAST(N'2019-02-01 18:22:00.000' AS DateTime))
GO
INSERT [dbo].[Attendance] ([EmpCode], [TimeIn], [TimeOut]) VALUES (1, CAST(N'2019-02-02 07:21:00.000' AS DateTime), NULL)
GO
INSERT [dbo].[Attendance] ([EmpCode], [TimeIn], [TimeOut]) VALUES (1, NULL, CAST(N'2019-02-02 19:54:00.000' AS DateTime))
GO
INSERT [dbo].[Employee] ([ID], [EmployeeName], [Department], [CenterCode]) VALUES (1, N'Asim', N'Information Tech', 4)
GO
INSERT [dbo].[Employee] ([ID], [EmployeeName], [Department], [CenterCode]) VALUES (2, N'Ali', N'Information Tech', 2)
GO
INSERT [dbo].[Employee] ([ID], [EmployeeName], [Department], [CenterCode]) VALUES (3, N'Isaac', N'Information Tech', 3)
GO
INSERT [dbo].[Employee] ([ID], [EmployeeName], [Department], [CenterCode]) VALUES (4, N'Swagger', N'Information Tech', 4)
GO
INSERT [dbo].[Employee] ([ID], [EmployeeName], [Department], [CenterCode]) VALUES (5, N'Nadine', N'Information Tech', 2)
GO
INSERT [dbo].[Employee] ([ID], [EmployeeName], [Department], [CenterCode]) VALUES (6, N'Julie', N'Information Tech', 4)
GO
INSERT [dbo].[Employee] ([ID], [EmployeeName], [Department], [CenterCode]) VALUES (7, N'Meachum', N'Information Tech', 3)
GO
INSERT [dbo].[Employee] ([ID], [EmployeeName], [Department], [CenterCode]) VALUES (8, N'Bob Lee', N'Information Tech', 4)
GO
ALTER TABLE [dbo].[Attendance] WITH CHECK ADD CONSTRAINT [FK_Attendance_Employee] FOREIGN KEY([EmpCode])
REFERENCES [dbo].[Employee] ([ID])
GO
ALTER TABLE [dbo].[Attendance] CHECK CONSTRAINT [FK_Attendance_Employee]
GO
Теперь я написал запрос, но поскольку я не уверен, как использовать функцию PIVOT без агрегатной функции, поэтому я использую MIN (), и именно поэтому он дает мне только первый тайм-аут / тайм-аут дня.
Вот запрос:
SELECT * FROM (
SELECT E.ID, E.EmployeeName, T.DateToCheck, COALESCE(A.val, 'Absent') val
FROM Employee E
CROSS JOIN (
SELECT CAST(DATEADD(DAY, number, '2019-02-01') AS DATE)
FROM master..spt_values
WHERE type = 'P'
AND DATEADD(DAY, number, '2019-02-01') <= '2019-02-28') T(DateToCheck)
LEFT JOIN (SELECT CAST(CAST(COALESCE(TimeIn, TimeOut) AS TIME) AS VARCHAR) val, CAST(COALESCE(TimeIn, TimeOut) AS DATE) AttendanceDateTime, EmpCode FROM Attendance) A ON CAST(A.AttendanceDateTime AS DATE) = T.DateToCheck AND A.EmpCode = E.ID
) T
PIVOT (MIN(val) FOR DateToCheck IN ([2019-02-01],[2019-02-02],[2019-02-03],[2019-02-04],[2019-02-05],[2019-02-06],[2019-02-07],[2019-02-08],[2019-02-09],[2019-02-10],[2019-02-11],[2019-02-12],[2019-02-13],[2019-02-14],[2019-02-15],[2019-02-16],[2019-02-17],[2019-02-18],[2019-02-19],[2019-02-20],[2019-02-21],[2019-02-22],[2019-02-23],[2019-02-24],[2019-02-25],[2019-02-26],[2019-02-27],[2019-02-28])) P;
Ожидаемый результат - что-то вроде этого
EmployeeName Status 2019-02-01 2019-02-02
Asim IN 06:30 07:21
Asim OUT 11:39 19:54
Asim IN 13:06 NULL
Asim OUT 18:22 NULL