Mysql 计算属于不同组集的最后x条记录的平均值
我试图计算找到零件id的最后两个批次的每个零件id的平均时间,以及所有批次的每个零件id的平均时间 我已成功分离出找到的最后两个批次的零件id的平均值,但我无法将其集成到代码中,以便它对每个零件id进行计算。我在“where子句”中得到一个错误未知列“tst.part\u id”,我需要将该tst.part\u id值传递给嵌套的select查询 下面是我的一把小提琴: 我使用的查询:Mysql 计算属于不同组集的最后x条记录的平均值,mysql,Mysql,我试图计算找到零件id的最后两个批次的每个零件id的平均时间,以及所有批次的每个零件id的平均时间 我已成功分离出找到的最后两个批次的零件id的平均值,但我无法将其集成到代码中,以便它对每个零件id进行计算。我在“where子句”中得到一个错误未知列“tst.part\u id”,我需要将该tst.part\u id值传递给嵌套的select查询 下面是我的一把小提琴: 我使用的查询: SELECT tst.part_id, AVG(tst.est_time) AS 'Average Tim
SELECT tst.part_id,
AVG(tst.est_time) AS 'Average Time Overall',
(SELECT AVG(ft.avgLastMax)
FROM
(SELECT t2.avglst as 'avgLastMax', t2.numval as 'numval'
FROM (SELECT
@num:=CASE WHEN @last != tst3.batch_id
THEN @num:=(@num + 1)
ELSE @num:=@num END 'numval',
@last:=tst3.batch_id,
@name:=CASE WHEN @num > 2
THEN @name:=@name
ELSE @name:=(tst3.est_time) END 'avglst'
FROM test AS tst3,
( select @last:=0, @avg := 0, @name :=0 , @num :=0) var
/* GET AVERAGE FOR A SINGLE PART ID
WHERE tst3.part_id = 1 */
WHERE tst3.part_id = tst.part_id
ORDER BY tst3.run_id DESC) as t2
)
as ft
WHERE ft.numval <3) as 'AVG on last 2 batches'
FROM test AS tst
GROUP BY tst.part_id;
表架构:
CREATE TABLE test
(`part_id` int, `est_time` int, `batch_id` int, `run_id` int, `line` varchar(1))
;
INSERT INTO test
(`part_id`, `est_time`, `batch_id`, `run_id`, `line`)
VALUES
(1, 20, 1, 1, 'T'),
(1, 25, 1, 2, 'T'),
(2, 30, 1, 3, 'T'),
(3, 15, 1, 4, 'T'),
(1, 10, 2, 5, 'X'),
(4, 40, 2, 8, 'X'),
(2, 15, 3, 9, 'T'),
(3, 15, 3, 10, 'T'),
(3, 20, 3, 11, 'T'),
(1, 34, 4, 12, 'X'),
(1, 32, 4, 13, 'X'),
(1, 33, 4, 14, 'X'),
(4, 55, 5, 15, 'T')
;
编辑:通过tst3更正了表格和订单。运行\u id DESC以获取最后一批\u id。假设您的第一个结果是错误的
SELECT W.*,T1.ALLAVG
FROM (
SELECT V.PART_ID, AVG(V.EST_TIME) LAST2 FROM
(
SELECT U.PART_ID,U.MAXRN,X.RUN_ID,X.EST_TIME
FROM
(
/*LAST 2*/
SELECT S.PART_ID,MAX(S.RN) MAXRN
FROM
(
/*DERIVE A ROW NUMBER*/
SELECT T.PART_ID , T.RUN_ID,
IF (CONCAT(T.PART_ID,T.RUN_ID) <> @R ,@RN:=@RN+1,@RN:=1) RN,
@R:=CONCAT(T.PART_ID,T.RUN_ID) R
FROM (SELECT @RN:=0,@P:=0,@R:=0) RN, TEST T
ORDER BY T.PART_ID,T.RUN_ID
) S
GROUP BY S.PART_ID
) U
/*USING THE MAX ABOVE GET THE LAST 2 */
JOIN
(SELECT T.PART_ID , T.RUN_ID,T.EST_TIME,
IF (CONCAT(T.PART_ID,T.RUN_ID) <> @R1 ,@RN1:=@RN1+1,@RN1:=1) RN,
@R1:=CONCAT(T.PART_ID,T.RUN_ID) R
FROM (SELECT @RN1:=0,@P1:=0,@R1:=0) RN, TEST T
ORDER BY T.PART_ID,T.RUN_ID
) X ON X.PART_ID = U.PART_ID AND (X.RN BETWEEN U.MAXRN -1 AND U.MAXRN) #AMEND THIS FOR THE LAST N REQUIRED
) V
GROUP BY V.PART_ID
) W
JOIN
/*ALL*/
(SELECT T.PART_ID,AVG(T.EST_TIME) 'ALLAVG' FROM TEST T GROUP BY T.PART_ID) T1 ON T1.PART_ID = W.PART_ID
SELECT a.part_id
, AVG(a.est_time)
FROM test a
JOIN
( SELECT x.part_id
, x.batch_id
FROM
( SELECT DISTINCT part_id
, batch_id
FROM test
) x
JOIN
( SELECT DISTINCT part_id
, batch_id
FROM test
) y
ON y.part_id = x.part_id
AND y.batch_id >= x.batch_id
GROUP
BY x.part_id
, x.batch_id
HAVING COUNT(*) <= 2
) b
ON b.part_id = a.part_id
AND b.batch_id = a.batch_id
GROUP
BY a.part_id;
+---------+-----------------+
| part_id | AVG(a.est_time) |
+---------+-----------------+
| 1 | 27.2500 |
| 2 | 22.5000 |
| 3 | 16.6667 |
| 4 | 47.5000 |
+---------+-----------------+
或者,更快。。。使用变量
SELECT part_id
, AVG(est_time) last_2_avg
FROM
( SELECT x.*
, CASE WHEN @part_id = part_id
THEN CASE WHEN @batch_id = batch_id THEN @i:=@i ELSE @i:=@i+1 END
ELSE @i:=1
END i
, @part_id := part_id
, @batch_id:= batch_id
FROM test x
, (SELECT @part_id := null, @batch_id:=null, @i:=1) vars
ORDER
BY part_id
, batch_id DESC
) a
WHERE a.i <= 2
GROUP
BY part_id;
+---------+------------+
| part_id | last_2_avg |
+---------+------------+
| 1 | 27.2500 |
| 2 | 22.5000 |
| 3 | 16.6667 |
| 4 | 47.5000 |
+---------+------------+
您预期输出中的数字似乎不符合要求。例如,part_id 1在最近两批中的平均值似乎为32.5。我错误地颠倒了顺序,part_id 1应该为27.25,33+32+34+10/4 part_id,batch_id,run_id是唯一的/主要的,对吗?@草莓run_id是AI和UQ@Strawberry否,批次id中可能存在重复的零件id,run_id是pki,您对上2个的计算是正确的,并且比我的代码干净得多。我将不得不在平均时间内加入这个结果
SELECT a.part_id
, AVG(a.est_time)
FROM test a
JOIN
( SELECT x.part_id
, x.batch_id
FROM
( SELECT DISTINCT part_id
, batch_id
FROM test
) x
JOIN
( SELECT DISTINCT part_id
, batch_id
FROM test
) y
ON y.part_id = x.part_id
AND y.batch_id >= x.batch_id
GROUP
BY x.part_id
, x.batch_id
HAVING COUNT(*) <= 2
) b
ON b.part_id = a.part_id
AND b.batch_id = a.batch_id
GROUP
BY a.part_id;
+---------+-----------------+
| part_id | AVG(a.est_time) |
+---------+-----------------+
| 1 | 27.2500 |
| 2 | 22.5000 |
| 3 | 16.6667 |
| 4 | 47.5000 |
+---------+-----------------+
SELECT part_id
, AVG(est_time) last_2_avg
FROM
( SELECT x.*
, CASE WHEN @part_id = part_id
THEN CASE WHEN @batch_id = batch_id THEN @i:=@i ELSE @i:=@i+1 END
ELSE @i:=1
END i
, @part_id := part_id
, @batch_id:= batch_id
FROM test x
, (SELECT @part_id := null, @batch_id:=null, @i:=1) vars
ORDER
BY part_id
, batch_id DESC
) a
WHERE a.i <= 2
GROUP
BY part_id;
+---------+------------+
| part_id | last_2_avg |
+---------+------------+
| 1 | 27.2500 |
| 2 | 22.5000 |
| 3 | 16.6667 |
| 4 | 47.5000 |
+---------+------------+