如何按列分组而不考虑其他列和 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

查找第一个和最后一个InOut
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

003OutTime 是否有错误?应该是 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

输出