我已经搜索过类似的问题,但没有成功。 下面的示例表。
ID | MO | Serial | PiID | Part_Number | Timestamp
1 | F610320 | 1 | QC1 | 4A130015 | 2017-05-10 09:55:28
2 | F610320 | 2 | QC1 | 4A130015 | 2017-05-10 10:12:54
3 | F610320 | 3 | QC1 | 4A130015 | 2017-05-10 10:19:47
4 | F631323 | 1 | QC2 | 4A110007B | 2017-05-10 10:20:24
5 | F631323 | 2 | QC2 | 4A110007B | 2017-05-10 10:21:50
6 | F631323 | 3 | QC3 | 4A110007B | 2017-05-10 10:31:02
7 | F631323 | 4 | QC3 | 4A110007B | 2017-05-10 10:31:02
在命令之后 SELECT A.*, COUNT(A.MO) FROM datalog A GROUP BY A.MO, A.PiID
我想要一个包含平均时间的列。 (不同的 MO
和 PiID
)
| MO | PiID | Part_Number |COUNT(MO)| average time
| F610320 | QC1 | 4A130015 | 3 | (10:19:47 - 09:55:28)/3-1
| F631323 | QC2 | 4A110007B | 2 |avg time between row by MO and PiID
| F631323 | QC3 | 4A110007B | 2 |avg time between row by MO and PiID
最佳答案
虽然 MySQL 允许在 SELECT
和 GROUP BY
子句之间进行一些奇怪的列组合,但标准 SQL 的一般规则是 “当使用聚合函数时,所有列在您的 SELECT
中也必须聚合或放在 GROUP BY
中”。
然后您要执行的操作需要这样的查询
select MO, PiID, Part_Number,
count(*) as CNT,
TIMESTAMPDIFF(SECOND,
min(Timestamp),
max(Timestamp)
) / (count(*) - 1) as Average_Time
from datalog
group by MO, PiID, Part_Number
having count(*) > 1
这将以秒为单位返回平均时间,但您也可以使用不同的时间单位。
请注意,计算平均时间差需要至少两个可用的时间戳,因此我添加了 HAVING
子句。否则,只有一行的 MO/PiID
组合会导致被零除。
编辑
仔细想想,实际上你不需要 HAVING 子句,因为如果 MO/PiID
组合有 1 行,则 min 和 max 将相同,因此差异将为 0,该查询的结果将为 0/0
,MySQL 会将其转换为 NULL
。
如果您希望显示其他内容而不是NULL
,您可以使用coalesce
函数
select MO, PiID, Part_Number,
count(*) as CNT,
TIMESTAMPDIFF(SECOND,
min(Timestamp),
max(Timestamp)
) / (count(*) - 1) as Average_Time,
COALESCE(TIMESTAMPDIFF(SECOND,
min(Timestamp),
max(Timestamp)
) / (count(*) - 1),
'something_else') as Average_Time_Coalesced
from datalog
group by MO, PiID, Part_Number
关于mysql - 具有不同列值的行的平均时间差,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43932564/