Sql 分组时使用XML路径操作行数据
在sql查询中,我尝试做两件事 我有一张这样的桌子 桌子 EID-雇员ID PID-点ID位置 D-白班 夜班 当我按除Shift以外的所有字段进行分组时,当仅对In_时间字段的日期部分进行分组时,我希望得到此值 中间步骤 最后,我想将其旋转以获得以下结果 预期最终结果 我在这里使用以下查询,但得到的结果略有不同Sql 分组时使用XML路径操作行数据,sql,sql-server,xml,winforms,pivot,Sql,Sql Server,Xml,Winforms,Pivot,在sql查询中,我尝试做两件事 我有一张这样的桌子 桌子 EID-雇员ID PID-点ID位置 D-白班 夜班 当我按除Shift以外的所有字段进行分组时,当仅对In_时间字段的日期部分进行分组时,我希望得到此值 中间步骤 最后,我想将其旋转以获得以下结果 预期最终结果 我在这里使用以下查询,但得到的结果略有不同 SELECT EID AS EmployeeID, [1],[2],[3],[4] FROM ( SELECT EID, datepart(dd,in_time) as [D
SELECT EID AS EmployeeID, [1],[2],[3],[4]
FROM (
SELECT
EID, datepart(dd,in_time) as [DAY],
STUFF((
SELECT '/ ' + Shift
FROM Attendance
WHERE ([in_time] = Results.[in_time] )
FOR XML PATH(''),TYPE).value('(./text())[1]','VARCHAR(MAX)')
,1,2,'') AS Shifts
FROM Attendance Results
WHERE EID = '100' AND PID ='C002'
GROUP BY EID , in_time
) AS SourceTable
PIVOT
(
MAX (Shifts )
FOR [DAY] IN ( [1],[2],[3],[4])
) AS PivotTable
这是查询的结果
EmployeeID | 01 | 02 | 03 | 04 |
________________________________
100 | D | _ | _ | N/N |
我的问题有点不对劲,你能帮我解决一下吗?我在这个查询中遗漏了什么?你知道更好的方法吗
编辑:我刚刚意识到,只要考勤表包含与单个员工和单点PID相关的记录,上述代码就可以正常工作
如果上表包含在不同PIDs位置工作的多个员工EIDs的详细信息,则输出是错误的。因此,我看到代码不一致,但我的sql知识似乎不足以在没有帮助的情况下解决这个问题:下面的答案可能会对您有所帮助。SQL看起来很长,但逻辑很简单,只需将D和N数据分组并最终合并。也许你可以从这里开始工作
DECLARE @Lu_Dt table
(id int identity(1,1),Dt Date)
INSERT INTO @Lu_Dt VALUES('2014-05-01'),
('2014-05-02'),('2014-05-03'),
('2014-05-04'),('2014-05-05')
DECLARE @tab table
(EID int,PID varchar(15),In_Time datetime,Out_Time datetime,[Shift] Char(1))
INSERT INTO @tab Values
(100,'S001','2014-05-01 07:10','2014-05-01 19:20','D'),
(100,'S001','2014-05-04 07:00','2014-05-04 19:00','D'),
(100,'S001','2014-05-04 19:00','2014-05-05 07:00','N')
SELECT * FROM @tab
结果
因为有很多硬编码,所以不能这样使用。希望这能有所帮助。Out\u Time=2014-05-05 07:00怎么样。它不会显示在您想要的结果中。你只是把准时视为员工的工作日吗?@Jithin Shaji,是的,轮班属于准时日。所以我不想出去玩了。Out_Time将只用于分类shiftsI删除了一些不需要的东西,使其更简单非常感谢。这有帮助。如果你不介意的话,你能解释一下代码的第二部分是以INSERT INTO@refTab开头的。。。这将非常有帮助。我将结果保存到临时表@refTab中,这样编写PIVOT语句看起来就不那么复杂了。
SELECT EID AS EmployeeID, [1],[2],[3],[4]
FROM (
SELECT
EID, datepart(dd,in_time) as [DAY],
STUFF((
SELECT '/ ' + Shift
FROM Attendance
WHERE ([in_time] = Results.[in_time] )
FOR XML PATH(''),TYPE).value('(./text())[1]','VARCHAR(MAX)')
,1,2,'') AS Shifts
FROM Attendance Results
WHERE EID = '100' AND PID ='C002'
GROUP BY EID , in_time
) AS SourceTable
PIVOT
(
MAX (Shifts )
FOR [DAY] IN ( [1],[2],[3],[4])
) AS PivotTable
EmployeeID | 01 | 02 | 03 | 04 |
________________________________
100 | D | _ | _ | N/N |
DECLARE @Lu_Dt table
(id int identity(1,1),Dt Date)
INSERT INTO @Lu_Dt VALUES('2014-05-01'),
('2014-05-02'),('2014-05-03'),
('2014-05-04'),('2014-05-05')
DECLARE @tab table
(EID int,PID varchar(15),In_Time datetime,Out_Time datetime,[Shift] Char(1))
INSERT INTO @tab Values
(100,'S001','2014-05-01 07:10','2014-05-01 19:20','D'),
(100,'S001','2014-05-04 07:00','2014-05-04 19:00','D'),
(100,'S001','2014-05-04 19:00','2014-05-05 07:00','N')
SELECT * FROM @tab
DECLARE @refTab table
(id int identity(1,1),EID int, Dt Date,[shift] varchar(3))
INSERT INTO @refTab
SELECT Lu.EID,Lu.Dt,coalesce(LU1.[Flag],LU2.[Flag]) [shift]
FROM (SELECT *,100 EID FROM @Lu_Dt) Lu
LEFT JOIN (SELECT D.EID,D.In_Time,'D/N' [Flag]
FROM (SELECT EID,CAST(In_Time AS DATE) In_Time FROM @tab Where Shift = 'D') D
JOIN (SELECT EID,CAST(In_Time AS DATE) In_Time FROM @tab Where Shift = 'N') N
ON D.In_Time = N.In_Time AND D.EID = N.EID) LU1 ON Lu.Dt = LU1.In_Time
LEFT JOIN (SELECT CAST(In_Time AS DATE) In_Time,'D' [Flag] FROM @tab Where Shift = 'D') LU2 ON Lu.Dt = LU2.In_Time
LEFT JOIN (SELECT CAST(In_Time AS DATE) In_Time,'N' [Flag] FROM @tab Where Shift = 'N') LU3 ON Lu.Dt = LU3.In_Time
SELECT * FROM @refTab
SELECT *
FROM (SELECT EID,Dt,[shift] from @refTab) As src
PIVOT
(MAX([shift]) for Dt in
( [2014-05-01],
[2014-05-02],
[2014-05-03],
[2014-05-04],
[2014-05-05])) AS PivotTable;