我正在 LeetCode.com 上解决这个问题:
列名称 类型 机器_id int 进程id int 活动类型 枚举 时间戳 漂浮
该表显示了工厂网站的用户活动。 (machine_id、process_id、activity_type) 是该表的主键(具有唯一值的列的组合)。 machine_id 是机器的 ID。 process_id 是在 ID 为 machine_id 的计算机上运行的进程的 ID。 Activity_type 是类型为 ('start', 'end') 的 ENUM(类别)。 时间戳是一个浮点数,表示当前时间(以秒为单位)。 “start”表示机器在给定时间戳开始进程,“end”表示机器在给定时间戳结束进程。 对于每个(machine_id,process_id)对,“开始”时间戳始终位于“结束”时间戳之前。
有一个工厂网站,有几台机器,每台机器都运行相同数量的进程。编写一个解决方案来找出每台机器完成一个过程所需的平均时间。
完成一个过程的时间是“结束”时间戳减去“开始”时间戳。平均时间的计算方法是:完成机器上每个进程的总时间除以已运行的进程数。
结果表应包含 machine_id 以及平均时间作为processing_time,应四舍五入到小数点后 3 位。
以任意顺序返回结果表。
我能够使用自连接解决这个问题,但我发现最佳实践是避免自连接,而是使用窗口函数。 但是,我不知道该怎么做(如果可能的话)。
我可以通过如下自连接解决问题:
select a1.machine_id, round(avg(a2.timestamp-a1.timestamp), 3) as processing_time
from Activity a1
join Activity a2
on a1.machine_id=a2.machine_id and a1.process_id=a2.process_id
and a1.activity_type='start' and a2.activity_type='end'
group by a1.machine_id
我还可以启动这样的窗口函数:
SELECT a1.machine_id, AVG(a1.timestamp) OVER (PARTITION BY machine_id) AS processing_time
FROM Activity AS a1
但是是否可以在聚合这些平均值时进行行级计算来减去时间? 另外,当我将 group by a1.machine_id 添加到底部时,我的上述代码(第二块)不起作用。 任何人都可以解释为什么吗?这是具体的错误:
[42000] [Microsoft][SQL Server 的 ODBC 驱动程序 17][SQL Server]列“Activity.timestamp”在选择列表中无效,因为它未包含在聚合函数或 GROUP BY 子句中。 (8120) (SQLExecDirectW)
窗口函数有点棘手,因为您想要的平均窗口将无法实现,因为您需要差异
您可以使用 LAG 或 LEAD 获取最后一行或下一行进行减法
CREATE TABLe Activity (machine_id int ,
process_id int,
activity_type VARCHAR(10) NOT NULL CHECK (activity_type IN('begin', 'end')),
timestamp float)
INSERT INTO Activity VALUES(1,1,'Begin', 1.2),(1,1,'End', 2.2),(1,2,'Begin', 3.2),(1,2,'End', 5.2)
WITH CTE AS (SELECT a1.machine_id, process_id
,
CASE WHEN activity_type = 'end' Then a1.timestamp
- LAG(a1.timestamp) OVER (PARTITION BY machine_id,process_id ORDER BY activity_type ) END
processing_time
FROM Activity AS a1)
SELECT machine_id,
AVG(processing_time) as processing_time
FROM CTE
WHERE processing_time IS NOT NULL
GROUP BY machine_id
机器_id | 处理时间 |
---|---|
1 | 1.5 |
select a1.machine_id, round(avg(a2.timestamp-a1.timestamp), 3) as processing_time
from Activity a1
join Activity a2
on a1.machine_id=a2.machine_id and a1.process_id=a2.process_id
and a1.activity_type='start' and a2.activity_type='end'
group by a1.machine_id
机器_id | 处理时间 |
---|