使用子查询的最小和最大结果查询
Query with Min and Max results from Subquery
我需要有关 sql 查询的帮助。我正在使用 Sql Server Management Studio,相关字段是:
Employees.Id
Employees.Name
Events.Employee_Id
Events.DateTime
什么是最有效的方法 return 每个员工/日期(不是日期时间)组合的一条记录,每个员工的名称、最小(日期时间)、最大(日期时间)和以小时为单位的增量/ 日期组合?
简单的方法是使用 Join
和 Min/Max
聚合
select e.Name,Min(ev.[DateTime]),Max(ev.[DateTime])
from Employees e
Left join Events ev --change it to INNER JOIN if you don't want all the employees
ON e.Id = ev.Employee_Id
Group by e.Name
另一种使用 Apply
运算符的方法
select e.Name,oa.MinDate,oa.MaxDate
from Employees e
Outer Apply( --change it to Cross Apply if you don't want all the employees
select Min(ev.[DateTime]),Max(ev.[DateTime])
from Events ev
Where e.Id = ev.Employee_Id) oa (MinDate,MaxDate
)
Window函数应该是最高效的方法。假设每个名字已经有一行并且 date/time:
select e.*,
max(e.datetime) over (partition by name),
min(e.datetime) over (partition by name),
(datediff(hours,
min(e.datetime) over (partition by name),
max(e.datetime) over (partition by name)
) as diff_in_hours
from events e;
非常感谢您的回复。这个问题一定不清楚,因为你们两个的解决方案都很相似,但不是我想要的。他们确实让我回去从头开始重试,我不确定我为什么不首先尝试这个,但下面是返回我正在寻找的结果。在我的问题中,我更改了 table/field 名称并省略了我知道我可以实现的要求,以使问题尽可能简单易读,这就是为什么它看起来如此不同:
SET DATEFIRST 1
SELECT e.IdEmpNum,
m.tFirstName,
m.tLastName,
convert(varchar(10), e.dtEventReal, 101) as "event_date",
convert(varchar(20), min(e.dtEventReal), 108) as "min",
convert(varchar(20), max(e.dtEventReal), 108) as "max",
round((datediff(minute,
min(e.dtEventReal),
max(e.dtEventReal)
)/60.0), 2) as "hours"
FROM tblEvents e INNER JOIN tblEmployees m ON e.IdEmpNum = m.iEmployeeNum
WHERE e.dtEventReal >= dateadd(day, 1-datepart(dw, getdate()), convert(date,getdate()))
GROUP BY e.IdEmpNum, m.tFirstName, m.tLastName, convert(varchar(10), e.dtEventReal, 101)
ORDER BY e.IdEmpNum, convert(varchar(10), e.dtEventReal, 101) ASC;
DATEFIRST 和 WHERE 条件指定仅返回本周的事件。我现在遇到的唯一问题是对 "hours" 计算求和。我收到一个错误,"SQL Server Cannot perform an aggregate function on an expression containing an aggregate or a subquery"。
我需要有关 sql 查询的帮助。我正在使用 Sql Server Management Studio,相关字段是:
Employees.Id
Employees.Name
Events.Employee_Id
Events.DateTime
什么是最有效的方法 return 每个员工/日期(不是日期时间)组合的一条记录,每个员工的名称、最小(日期时间)、最大(日期时间)和以小时为单位的增量/ 日期组合?
简单的方法是使用 Join
和 Min/Max
聚合
select e.Name,Min(ev.[DateTime]),Max(ev.[DateTime])
from Employees e
Left join Events ev --change it to INNER JOIN if you don't want all the employees
ON e.Id = ev.Employee_Id
Group by e.Name
另一种使用 Apply
运算符的方法
select e.Name,oa.MinDate,oa.MaxDate
from Employees e
Outer Apply( --change it to Cross Apply if you don't want all the employees
select Min(ev.[DateTime]),Max(ev.[DateTime])
from Events ev
Where e.Id = ev.Employee_Id) oa (MinDate,MaxDate
)
Window函数应该是最高效的方法。假设每个名字已经有一行并且 date/time:
select e.*,
max(e.datetime) over (partition by name),
min(e.datetime) over (partition by name),
(datediff(hours,
min(e.datetime) over (partition by name),
max(e.datetime) over (partition by name)
) as diff_in_hours
from events e;
非常感谢您的回复。这个问题一定不清楚,因为你们两个的解决方案都很相似,但不是我想要的。他们确实让我回去从头开始重试,我不确定我为什么不首先尝试这个,但下面是返回我正在寻找的结果。在我的问题中,我更改了 table/field 名称并省略了我知道我可以实现的要求,以使问题尽可能简单易读,这就是为什么它看起来如此不同:
SET DATEFIRST 1
SELECT e.IdEmpNum,
m.tFirstName,
m.tLastName,
convert(varchar(10), e.dtEventReal, 101) as "event_date",
convert(varchar(20), min(e.dtEventReal), 108) as "min",
convert(varchar(20), max(e.dtEventReal), 108) as "max",
round((datediff(minute,
min(e.dtEventReal),
max(e.dtEventReal)
)/60.0), 2) as "hours"
FROM tblEvents e INNER JOIN tblEmployees m ON e.IdEmpNum = m.iEmployeeNum
WHERE e.dtEventReal >= dateadd(day, 1-datepart(dw, getdate()), convert(date,getdate()))
GROUP BY e.IdEmpNum, m.tFirstName, m.tLastName, convert(varchar(10), e.dtEventReal, 101)
ORDER BY e.IdEmpNum, convert(varchar(10), e.dtEventReal, 101) ASC;
DATEFIRST 和 WHERE 条件指定仅返回本周的事件。我现在遇到的唯一问题是对 "hours" 计算求和。我收到一个错误,"SQL Server Cannot perform an aggregate function on an expression containing an aggregate or a subquery"。