根据距离最近的较小邻居

时间:2017-06-30 13:10:28

标签: mysql

我有一个列A的表是INT(11)(它是一个时间戳,但现在我只使用小数字)

id |  A | diff |
---+----+------+
 1 | 12 |      |
 2 |  7 |      |
 3 | 23 |      |
 4 |  9 |      |
 5 |  2 |      |
 6 | 30 |      |

我希望更新diff A最近的小邻居之间的差异。因此,如果A=12它的第一个较小的neightbour是A=7,如果A=30它是A=23。我应该得到一个这样的表格(按A排序):

id |  A | diff |
---+----+------+
 5 |  2 |  -   |
 2 |  7 |  5   | (7-5)
 4 |  9 |  2   | (9-7)
 1 | 12 |  3   | (12-9)
 3 | 23 | 11   | (23-12)
 6 | 30 |  7   | (30-23)

我可以计算插入时的差异,因为我知道A然后(这里:A=15):

INSERT INTO `table` (`A`,`diff`)
    (SELECT 15 , 15-`A` FROM `table` WHERE `A` < 15 ORDER BY `A` DESC LIMIT 1)

这会产生新记录:

id |  A | diff |
---+----+------+
 7 | 15 |  3   |   (3 being the difference between A=12 and A=15

注意:A=1成为新的最小值且没有较小的邻居时,这会失败,因此没有值diff

但是现在记录3中diff的值是错误的,因为它仍然基于23 - 12之间的差异,现在应该是23 - 15

所以我只想插入A值,然后在桌面上运行更新,刷新diff necessery。但那是我对MYSQL知识的结束......

我制作了这个查询,却没有说“你不能指定表格&#39; t1&#39;用于FROM子句中的更新

UPDATE `table` AS t1
SET 
t1.`diff` = t1.`A` - (SELECT `A` FROM `table` 
                      WHERE `A` < t1.`A` 
                  ORDER BY `A` DESC LIMIT 1
                  ) 

2 个答案:

答案 0 :(得分:2)

这是一个查询:

SELECT x.*
     , x.a-MAX(y.a) diff 
  FROM my_table x 
  LEFT 
  JOIN my_table y  
    ON y.a < x.a 
 GROUP 
    BY x.id 
 ORDER 
    BY a;

我不确定你为什么要存储派生数据,但你可以猜测......

UPDATE my_table m
  JOIN 
     ( SELECT x.*
            , x.a-MAX(y.a) q
         FROM my_table x 
         JOIN my_table y 
           ON y.a < x.a 
        GROUP 
           BY x.id
     ) n
    ON n.id = m.id 
   SET m.diff = q;

答案 1 :(得分:0)

您可以在插入新值后尝试此操作:

UPDATE x
SET
x.diff = iq2.new_diff 
FROM
#t x
 INNER JOIN
   (SELECt id,A,diff , new_diff 
     FROM
     (select id,A,15 as new_number, 
             CASE WHEN (A-15) < 0 THEN NULL ELSE (A-15) END as new_diff,diff 
      from #t
     ) iq
   WHERE 
   iq.new_diff <= iq.diff 
   AND iq.new_diff <> 0
  )iq2
on x.A = iq2.A

内部查询比较先前的差异和当前差异,然后更新相关的差异。