SQL 交叉制表、数据透视表
SQL Cross-Tabulation, Pivot
我在一家需要改进轮班管理概览的公司工作。他们习惯于 excel sheet,而我打算改为在 Web 浏览器上实施解决方案。 sheet 的格式是这样的:
Employee1 Employee2 Employee3
DD/MM/YYY1 Mon Shift1 Shift2 Shift3
DD/MM/YYY2 Tue Shift2 Shift3 Shift1
DD/MM/YYY3 Wed Shift3 Shift1 Shift2
DD/MM/YYY4 Thu Shift1 Shift2 Shift3
DD/MM/YYY5 Fri Shift2 Shift3 Shift1
我的问题是现在,它看起来像这样:
Date Shift_Type_Name Employee_Name
DD/MM/YYY1 Mon Shift1 Employee1
DD/MM/YYY1 Mon Shift2 Employee2
DD/MM/YYY1 Mon Shift3 Employee3
我正在使用 ASP.net 4.6.1 和 Microsoft SQL Server.
我会为感兴趣的人附上数据库设计的照片。
我应该关注SQL查询为每个员工动态添加一列,还是应该使用ListView模板 在这个设计中显示它等等?
感谢您的关注和帮助。我从这个社区中受益匪浅。 :)
编辑:
我最接近我的问题的解决方案(也许这会帮助你更好地理解我的问题)是这个伪代码:
SELECT
[Date].[date] AS 'Date',
FOR EACH( SELECT [Employee].* AS THIS ){
SELECT [Shift_Type].[name] AS [THIS].[Name] + ' Morning',
WHERE [Shifts].[Type] = @morning_hours AND [Shifts].[Employee_fk] = [THIS].[ID]
SELECT [Shift_Type].[name] AS [THIS].[Name] + ' Evening',
WHERE [Shifts].[Type] = @evening_hours AND [Shifts].[Employee_fk] = [THIS].[ID]
}
FROM [Groups]
JOIN [Employee]
ON [Groups].[id] = [Employee].[group_fk]
JOIN [Shifts]
ON [Employee].[id] = [Shifts].[employee_fk]
JOIN [Shift_Types]
ON [Shift_Types].[id] = [Shifts].[type_fk]
RIGHT JOIN [Date]
ON [Date].[id] = [Shifts].[date_fk]
JOIN [Public_Holidays]
ON [Public_Holidays].[date_fk] = [Date].[id]
我知道 FOR EACH 在 SQL 服务器中不是一个选项,但希望这描述了我正在努力实现的目标。
经过一些额外的研究,我发现 this video 对解释旋转非常有帮助。
这是我在它的帮助下进行的查询:
DECLARE @ColumnNames NVARCHAR(MAX) = '';
DECLARE @SQuery NVARCHAR(MAX) = '';
SELECT @ColumnNames += QUOTENAME(Employee.name) + ','
FROM Employee;
SET @ColumnNames =LEFT(@ColumnNames, LEN(@ColumnNames) - 1);
SET @SQuery =
'
SELECT * FROM
(SELECT
Employee.name as Name,
Date.date as ''Date'',
Shift_Types.name as ''Shift''
FROM [Groups]
JOIN [Employee]
ON [Groups].[id] = [Employee].[group_fk]
JOIN [Shifts]
ON [Employee].[id] = [Shifts].[employee_fk]
JOIN [Shift_Types]
ON [Shift_Types].[id] = [Shifts].[type_fk]
RIGHT JOIN [Date]
ON [Date].[id] = [Shifts].[date_fk]
JOIN [Public_Holidays]
ON [Public_Holidays].[date_fk] = [Date].[id]) as BaseData
PIVOT(
MIN(BaseData.[Shift])
FOR BaseData.[Name]
IN (' + @ColumnNames + ')
) as PivotTable'
EXEC(@SQuery);
我希望这对某人有所帮助。 :)
我在一家需要改进轮班管理概览的公司工作。他们习惯于 excel sheet,而我打算改为在 Web 浏览器上实施解决方案。 sheet 的格式是这样的:
Employee1 Employee2 Employee3
DD/MM/YYY1 Mon Shift1 Shift2 Shift3
DD/MM/YYY2 Tue Shift2 Shift3 Shift1
DD/MM/YYY3 Wed Shift3 Shift1 Shift2
DD/MM/YYY4 Thu Shift1 Shift2 Shift3
DD/MM/YYY5 Fri Shift2 Shift3 Shift1
我的问题是现在,它看起来像这样:
Date Shift_Type_Name Employee_Name
DD/MM/YYY1 Mon Shift1 Employee1
DD/MM/YYY1 Mon Shift2 Employee2
DD/MM/YYY1 Mon Shift3 Employee3
我正在使用 ASP.net 4.6.1 和 Microsoft SQL Server.
我会为感兴趣的人附上数据库设计的照片。
我应该关注SQL查询为每个员工动态添加一列,还是应该使用ListView模板 在这个设计中显示它等等?
感谢您的关注和帮助。我从这个社区中受益匪浅。 :)
编辑: 我最接近我的问题的解决方案(也许这会帮助你更好地理解我的问题)是这个伪代码:
SELECT
[Date].[date] AS 'Date',
FOR EACH( SELECT [Employee].* AS THIS ){
SELECT [Shift_Type].[name] AS [THIS].[Name] + ' Morning',
WHERE [Shifts].[Type] = @morning_hours AND [Shifts].[Employee_fk] = [THIS].[ID]
SELECT [Shift_Type].[name] AS [THIS].[Name] + ' Evening',
WHERE [Shifts].[Type] = @evening_hours AND [Shifts].[Employee_fk] = [THIS].[ID]
}
FROM [Groups]
JOIN [Employee]
ON [Groups].[id] = [Employee].[group_fk]
JOIN [Shifts]
ON [Employee].[id] = [Shifts].[employee_fk]
JOIN [Shift_Types]
ON [Shift_Types].[id] = [Shifts].[type_fk]
RIGHT JOIN [Date]
ON [Date].[id] = [Shifts].[date_fk]
JOIN [Public_Holidays]
ON [Public_Holidays].[date_fk] = [Date].[id]
我知道 FOR EACH 在 SQL 服务器中不是一个选项,但希望这描述了我正在努力实现的目标。
经过一些额外的研究,我发现 this video 对解释旋转非常有帮助。
这是我在它的帮助下进行的查询:
DECLARE @ColumnNames NVARCHAR(MAX) = '';
DECLARE @SQuery NVARCHAR(MAX) = '';
SELECT @ColumnNames += QUOTENAME(Employee.name) + ','
FROM Employee;
SET @ColumnNames =LEFT(@ColumnNames, LEN(@ColumnNames) - 1);
SET @SQuery =
'
SELECT * FROM
(SELECT
Employee.name as Name,
Date.date as ''Date'',
Shift_Types.name as ''Shift''
FROM [Groups]
JOIN [Employee]
ON [Groups].[id] = [Employee].[group_fk]
JOIN [Shifts]
ON [Employee].[id] = [Shifts].[employee_fk]
JOIN [Shift_Types]
ON [Shift_Types].[id] = [Shifts].[type_fk]
RIGHT JOIN [Date]
ON [Date].[id] = [Shifts].[date_fk]
JOIN [Public_Holidays]
ON [Public_Holidays].[date_fk] = [Date].[id]) as BaseData
PIVOT(
MIN(BaseData.[Shift])
FOR BaseData.[Name]
IN (' + @ColumnNames + ')
) as PivotTable'
EXEC(@SQuery);
我希望这对某人有所帮助。 :)