如何按列分组而不考虑其他列和 return 所有对应行?
How to Group by a column irrespective of other column and return all corresponding rows?
我在 table AttendanceReg 中有员工的移动数据,例如:
EmpId
InPlace
InTime
OutTime
001
Plc01
10AM
11AM
002
Plc01
10AM
11AM
001
Plc02
11AM
12PM
002
Plc02
11AM
07PM
001
Plc01
12PM
06PM
003
Plc01
10AM
08PM
我想要一份员工报告
第一进,最后进出它的位置。
(应该取决于进出时间,而不是地点)
当我尝试聚合函数和分组依据时,它 returned:
Alter PROCEDURE UDP_AttReport @SelectDt Date
AS
select EmpID as ID,max(InPlace) as InPlace,min(InTime) as InTime Into #AttIN from AttendanceReg where cast(InTime as Date) = cast(@SelectDt as date) group by EmpID order by InTime desc
select EmpID as ID, max(InPlace)as OutPlace,max(OutTime) as OutTime Into #AttOut from AttendanceReg where cast(InTime as Date) = cast(@SelectDt as date) group by EmpID order by OutTime desc
SELECT #AttIN.ID,InPlace,InTime,OutPlace,OutTime Into #AttRep FROM #AttIN
RIGHT JOIN #AttOut
ON #AttIN.ID = #AttOut.ID
select ID,InPlace,InTime,OutPlace,OutTime from #AttRep Order by InTime asc
drop table #AttIN
drop table #AttOut
drop table #AttRep
Go
EmpId
InPlace
InTime
OutPlace
OutTime
001
Plc02
10AM
Plc02
06PM
002
Plc02
11AM
Plc02
07PM
003
Plc01
10AM
Plc01
08AM
但我期望的是
EmpId
InPlace
InTime
OutPlace
OutTime
001
Plc01
10AM
Plc01
06PM
002
Plc01
10AM
Plc02
07PM
003
Plc01
10AM
Plc01
08PM
我可以理解问题出在使用 Max(InPlace) 上(我在某处学到它可以在不按该列分组的情况下将 SQL 欺骗到 return 列)。
谢谢。
使用window函数row_number()
通过EmpId
查找第一个和最后一个In
或Out
with cte as
(
select *,
rn = row_number() over (partition by EmpId order by InTime),
rc = count(*) over (partition by EmpId)
from AttendanceReg
)
select EmpId,
InPlace = max(case when rn = 1 then InPlace end),
InTime = max(case when rn = 1 then InTime end),
OutPlace = max(case when rn = rn then InPlace end),
OutTime = max(case when rn = rn then OutTime end)
from cte
group by EmpId
003
的 OutTime
是否有错误?应该是 08PM
?
试试这个:
Select a.EmpId,
a.InPlace,
a.InTime,
b.Inplace as Outplace ,
b.OutTime
From
(Select EmpId, InPlace, InTime, ROW_NUMBER() over(partition by EmpId order by InTime) rn From test) a
inner join
(Select EmpId, InPlace, OutTime, ROW_NUMBER() over(partition by EmpId order by OutTime desc) rn From test) b
on
a.EmpId = b.EmpId
Where
a.rn = 1
and b.rn = 1
输出
我在 table AttendanceReg 中有员工的移动数据,例如:
EmpId | InPlace | InTime | OutTime |
---|---|---|---|
001 | Plc01 | 10AM | 11AM |
002 | Plc01 | 10AM | 11AM |
001 | Plc02 | 11AM | 12PM |
002 | Plc02 | 11AM | 07PM |
001 | Plc01 | 12PM | 06PM |
003 | Plc01 | 10AM | 08PM |
我想要一份员工报告 第一进,最后进出它的位置。 (应该取决于进出时间,而不是地点)
当我尝试聚合函数和分组依据时,它 returned:
Alter PROCEDURE UDP_AttReport @SelectDt Date
AS
select EmpID as ID,max(InPlace) as InPlace,min(InTime) as InTime Into #AttIN from AttendanceReg where cast(InTime as Date) = cast(@SelectDt as date) group by EmpID order by InTime desc
select EmpID as ID, max(InPlace)as OutPlace,max(OutTime) as OutTime Into #AttOut from AttendanceReg where cast(InTime as Date) = cast(@SelectDt as date) group by EmpID order by OutTime desc
SELECT #AttIN.ID,InPlace,InTime,OutPlace,OutTime Into #AttRep FROM #AttIN
RIGHT JOIN #AttOut
ON #AttIN.ID = #AttOut.ID
select ID,InPlace,InTime,OutPlace,OutTime from #AttRep Order by InTime asc
drop table #AttIN
drop table #AttOut
drop table #AttRep
Go
EmpId | InPlace | InTime | OutPlace | OutTime |
---|---|---|---|---|
001 | Plc02 | 10AM | Plc02 | 06PM |
002 | Plc02 | 11AM | Plc02 | 07PM |
003 | Plc01 | 10AM | Plc01 | 08AM |
但我期望的是
EmpId | InPlace | InTime | OutPlace | OutTime |
---|---|---|---|---|
001 | Plc01 | 10AM | Plc01 | 06PM |
002 | Plc01 | 10AM | Plc02 | 07PM |
003 | Plc01 | 10AM | Plc01 | 08PM |
我可以理解问题出在使用 Max(InPlace) 上(我在某处学到它可以在不按该列分组的情况下将 SQL 欺骗到 return 列)。
谢谢。
使用window函数row_number()
通过EmpId
In
或Out
with cte as
(
select *,
rn = row_number() over (partition by EmpId order by InTime),
rc = count(*) over (partition by EmpId)
from AttendanceReg
)
select EmpId,
InPlace = max(case when rn = 1 then InPlace end),
InTime = max(case when rn = 1 then InTime end),
OutPlace = max(case when rn = rn then InPlace end),
OutTime = max(case when rn = rn then OutTime end)
from cte
group by EmpId
003
的 OutTime
是否有错误?应该是 08PM
?
试试这个:
Select a.EmpId,
a.InPlace,
a.InTime,
b.Inplace as Outplace ,
b.OutTime
From
(Select EmpId, InPlace, InTime, ROW_NUMBER() over(partition by EmpId order by InTime) rn From test) a
inner join
(Select EmpId, InPlace, OutTime, ROW_NUMBER() over(partition by EmpId order by OutTime desc) rn From test) b
on
a.EmpId = b.EmpId
Where
a.rn = 1
and b.rn = 1
输出