Mysql 计算属于不同组集的最后x条记录的平均值

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

我试图计算找到零件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 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 |
+---------+------------+