我对SQL有很好的理解(无论如何,我认为)。足够形成合理的查询并获得我想要的数据,尽管并不总是最好的格式。
我有以下查询;
DECLARE @StartDate DATE = '2014-07-01'
DECLARE @EndDate DATE = '2014-07-16'
SELECT Name, [Leave Type], SUM([Days Taken]) AS [Days Taken]
FROM(
SELECT LR.idLeaveRequest, U.Name, LR.[start date], LR.[end date], SUM(DATEDIFF(DAY, LR.[start date], LR.[end date])) + 1 AS [Days Taken],
L.LeaveType AS [Leave Type]
FROM LeaveRequests LR
INNER JOIN Users U ON U.idUser = LR.id_User
INNER JOIN Leave L ON L.idLeave = LR.id_LeaveType
WHERE @StartDate <= CAST([start date] AS DATE) AND @EndDate >= CAST([end date] AS DATE) AND id_Status = 3
GROUP BY LR.idLeaveRequest, U.Name, LR.[start date], LR.[end date], L.LeaveType) AS Original
GROUP BY [Leave Type], Name
哪个获取数据,但它并不是最好的格式,因为“Joe”可能在Lieu有3天的年假和3天的离开,这意味着Joe有两行。理想情况下,它将是1行和2列。
我认为我需要做一个PIVOT (MAX([Days Taken]) ON [Leave Type])
,但我不确定是否可以从LeaveType表中动态获取列?此外,我不是100%肯定构建数据透视表的思考过程,我想如果有人能够解释从头开始(或从我目前所在的位置)开始可视化/构建表的最佳方法,我认为这对我来说还有很长的路要走,不需要再次寻求帮助。
(我不能使用除原始SQL之外的任何东西,因为这将进入一个程序,根据SQL查询的结果生成一个很好的报告)
表格数据
LeaveRequests
idLeaveRequest int PK
start date DATE
end date DATE
id_Status int
id_LeaveType int
id_User int
Leave
idLeave int PK
LeaveType varchar
User
idUser int PK
Name varchar
当前输出
Name | Leave Type | Days Taken
Joe | RDO | 5
Joe | Annual | 2
所需输出
Name | Annual | RDO
Joe | 2 | 5
答案 0 :(得分:0)
使用以下查询以获得动态数据透视:
DECLARE @columns NVARCHAR(1000) = '',
@sql NVARCHAR(MAX)
SELECT @Columns = STUFF((SELECT ',['+[Leave Type]+']'
FROM(
SELECT DISTINCT L.LeaveType AS [Leave Type]
FROM LeaveRequests LR
INNER JOIN Users U ON U.idUser = LR.id_User
INNER JOIN Leave L ON L.idLeave = LR.id_LeaveType
WHERE @StartDate <= CAST([start date] AS DATE) AND @EndDate >= CAST([end date] AS DATE) AND id_Status = 3
) AS Original
FOR XML PATH('')),1,1,'')
SET @sql = 'DECLARE @StartDate DATE = ''2014-07-01''
DECLARE @EndDate DATE = ''2014-07-16''
SELECT *
FROM (
SELECT Name, [Leave Type], SUM([Days Taken]) AS [Days Taken]
FROM(
SELECT LR.idLeaveRequest, U.Name, LR.[start date], LR.[end date], SUM(DATEDIFF(DAY, LR.[start date], LR.[end date])) + 1 AS [Days Taken],
L.LeaveType AS [Leave Type]
FROM LeaveRequests LR
INNER JOIN Users U ON U.idUser = LR.id_User
INNER JOIN Leave L ON L.idLeave = LR.id_LeaveType
WHERE @StartDate <= CAST([start date] AS DATE) AND @EndDate >= CAST([end date] AS DATE) AND id_Status = 3
GROUP BY LR.idLeaveRequest, U.Name, LR.[start date], LR.[end date], L.LeaveType) AS Original
GROUP BY [Leave Type], Name)p
PIVOT (MAX([Days Taken]) FOR [Leave Type] IN ('+@columns+')Pvt'
EXECUTE(@sql)
答案 1 :(得分:0)
非动态的一般形式是:
DECLARE @StartDate DATE = '2014-07-01'
DECLARE @EndDate DATE = '2014-07-16'
SELECT Name,
SUM(CASE WHEN [Leave Type] = 'RDO' THEN [Days Taken] ELSE 0 END) AS RDO,
SUM(CASE WHEN [Leave Type] = 'Annual' THEN [Days Taken] ELSE 0 END) AS Annual
FROM(
SELECT LR.idLeaveRequest, U.Name, LR.[start date], LR.[end date],
SUM(DATEDIFF(DAY, LR. [start date], LR.[end date])) + 1 AS [Days Taken],
L.LeaveType AS [Leave Type]
FROM LeaveRequests LR
INNER JOIN Users U ON U.idUser = LR.id_User
INNER JOIN Leave L ON L.idLeave = LR.id_LeaveType
WHERE @StartDate <= CAST([start date] AS DATE) AND
@EndDate >= CAST([end date] AS DATE) AND id_Status = 3
GROUP BY LR.idLeaveRequest, U.Name, LR.[start date],
LR.[end date], L.LeaveType) AS Original
GROUP BY Name