Использование PIVOT без какой-либо агрегатной функции - PullRequest
0 голосов
/ 24 апреля 2019

У меня есть такая структура таблиц, которая ежедневно посещает сотрудников магазина. Я хочу получить результат, чтобы я мог узнать под датой, сколько раз сотрудник отмечал посещаемость, если он регистрировался, он давал какой-либо статус, скажем, 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...