Mysql 使用总和和限制、滚动总和进行更新

Mysql 使用总和和限制、滚动总和进行更新,mysql,sql-update,Mysql,Sql Update,我有两张桌子,SVISE和OVERW 在Over内部,我有一些个人ID的分数和分数日期。 例如 SVISE.ofh字段必须使用最后三条记录的总和进行更新 对于特定的人,按日期降序排列,因此对于id为5的人,总和将从行中得出 5 10.2 2013-10-09 5 5.45 2013-08-11 5 6.2 2013-06-10 总和=21.85 基于上述值,SVISE的预期最终结果: HID OFH START

我有两张桌子,SVISE和OVERW

在Over内部,我有一些个人ID的分数和分数日期。 例如

SVISE.ofh字段必须使用最后三条记录的总和进行更新 对于特定的人,按日期降序排列,因此对于id为5的人,总和将从行中得出

5        10.2      2013-10-09
5        5.45      2013-08-11
5        6.2       2013-06-10
总和=21.85

基于上述值,SVISE的预期最终结果:

HID OFH     START
5   21.85   October, 16 2013   ##(10.2 + 5.45 + 6.2)
5   21.5    September, 07 2013 ##(5.45 + 6.2 + 9.85)
5   0       March, 05 2013     ##(no rows)
8   25.75   October, 14 2013   ##(14.75 + 11)
3   0       October, 14 2013   ##(no rows)
5   0       March, 05 2012     ##(no rows)
最初是0

我可以得到一个人的总数,但我不能用limit来得到最后3行。它被忽略了

这是我用来检索给定日期每人所有学位总和的查询:

UPDATE SVISE SV
SET 
SV.ofh=(SELECT sum(degrees) FROM OVERW WHERE p_id =SV.hid 
AND date(mo_date)<date(SV.start) 
AND year(mo_date)=year(SV.start))
我不能只使用限制和总和:

UPDATE SVISE SV
SET 
SV.ofh=(SELECT sum(degrees) FROM OVERW WHERE p_id =SV.hid 
AND date(mo_date)<date(SV.start) 
AND year(mo_date)=year(SV.start)
ORDER BY mo_date DESC 
LIMIT 3)
这是行不通的

为了实现这一点,我尝试了多表更新和嵌套查询。 每个场景都有一些已知的限制,这些限制阻碍了我实现预期的结果

嵌套查询无法看到父表。where子句中的未知列“SV.hid” 多表更新不能与限制一起使用。更新和限制的不正确使用 任何解决方案都可以。不需要在单个查询中执行此操作。如果有人想尝试使用中间表

此外,还提供了一个

提前感谢你的帮助

-更新-

以下是来自Akash的解决方案:

试试看

UPDATE svice SV
JOIN (SELECT SUM(degrees)sumdeg,p_id FROM(SELECT DISTINCT degrees,p_id FROM OVERW,svice WHERE OVERW.p_id IN (SELECT svice.hid FROM svice) 
AND date(mo_date)<date(svice.start) 
AND year(mo_date)=year(svice.start)ORDER BY mo_date DESC )deg  group by p_id)bbc 
      ON bbc.p_id=SV.hid 
      SET 
SV.ofh=bbc.sumdeg where p_id =SV.hid 
越来越近了,现在它只需要在GROUP BY中设置一个限制。

这应该行得通

更新为在svice上加入

注:请使用更新的数据进行检查,由于日期条件的原因,提供的测试数据无法产生您预期的结果

两个假设:

您可以找出如何将其转换为更新 在id、MOU日期上存在PK 那么你可以这样做-

SELECT p_id
     , SUM(degrees) ttl
  FROM 
     ( SELECT x.*
         FROM overw x 
         JOIN overw y 
           ON y.p_id = x.p_id 
          AND y.mo_date >= x.mo_date 
        GROUP 
           BY p_id
            , mo_date HAVING COUNT(*) <= 3
     ) a 
 GROUP 
    BY p_id;

也许我很慢,但我们暂时忽略斯维兹。 你能为下面的每一行显示正确的结果和工作方式吗

+------+---------+------------+--------+
| p_id | degrees | mo_date    | result |
+------+---------+------------+--------+
|    5 |    6.20 | 2013-06-10 |      ? | 
|    5 |    5.45 | 2013-08-11 |      ? |
|    5 |   10.20 | 2013-10-09 |  21.85 | <- = 10.2+5.45+6.2 = 21.85 
|    8 |   14.75 | 2013-04-25 |      ? |
|    5 |    9.85 | 2013-03-10 |      ? |
|    8 |   11.00 | 2013-02-22 |      ? |  
+------+---------+------------+--------+

米海,我摆好了小提琴。我已经在我的问题中粘贴了小提琴链接。你会注意到结果值是错误的,我无法让它更新所有的行,需要一个更有知识的人。非常感谢你在查询中的努力,你正在验证年份是否匹配。这是要求的一部分吗?另外,根据SQL FIDLE,SVISE或svice的主键由哪些列组成?@AndriyM,我想要一个人的最后3度,唯一的过滤器是日期。从现在起的最后3度或从昨天起的最后3度等。此数据集是否与SQLFIDLE中提供的数据集相对应?如果没有,考虑为SqLFIDLE数据集提供正确的结果集,并相应地更新您的问题。只为OVW表提供完整的结果集是明智的。另外,你确定这些结果集应该是浮点而不是十进制吗?嗨,草莓,是的,它是相同的数据集,我将十进制改为浮点只是为了让人们更容易直观地理解它,以及一些随机数据。Fiddle结构是一样的,你可以修改它,插入任何你喜欢的行,甚至让它包含与问题相同的行。谢谢,但我需要使用一个日期过滤器。我需要使用WHERE datemo_date如果每个svice记录都有一个对应的OVER p_id条目,你可以直接在最里面的查询中进行连接。如果SVISE表,每个p_id都有一个条目?在每行中,svice表都有一个日期,基于此,我需要找到3度OVER的总和,对于SVICE的每一行。但是SVISE表对于每个overw p_id只有一个条目吗?在这里试一试:sqlfiddle.com/!2/64d96/1Strawberry,结果不应分组,请检查我问题中没有意义的期望结果。早些时候,您可以在不参考任何其他表的情况下,获得上面第3行的中间结果10.2+5.45+6.2=21.85。在这里,我插入了您的数据,以便您可以检查它,AkashWiddle的解决方案似乎已关闭!
SELECT p_id
     , SUM(degrees) ttl
  FROM 
     ( SELECT x.*
         FROM overw x 
         JOIN overw y 
           ON y.p_id = x.p_id 
          AND y.mo_date >= x.mo_date 
        GROUP 
           BY p_id
            , mo_date HAVING COUNT(*) <= 3
     ) a 
 GROUP 
    BY p_id;
+------+---------+------------+--------+
| p_id | degrees | mo_date    | result |
+------+---------+------------+--------+
|    5 |    6.20 | 2013-06-10 |      ? | 
|    5 |    5.45 | 2013-08-11 |      ? |
|    5 |   10.20 | 2013-10-09 |  21.85 | <- = 10.2+5.45+6.2 = 21.85 
|    8 |   14.75 | 2013-04-25 |      ? |
|    5 |    9.85 | 2013-03-10 |      ? |
|    8 |   11.00 | 2013-02-22 |      ? |  
+------+---------+------------+--------+