使用SUM和LIMIT更新,滚动SUM

时间:2013-10-14 00:38:44

标签: mysql sql-update

我有2个表, SVISE OVERW

OVERW 里面,我有一些人员ID和得分日期。 E.g

p_id    degrees    mo_date
5        10.2      2013-10-09
5        9.85      2013-03-10
8        14.75     2013-04-25
8        11.00     2013-02-22
5        5.45      2013-08-11
5        6.2       2013-06-10
必须使用最后三条记录的总和来更新 SVISE.ofh 字段 (对于特定的人,按日期降序排序),因此对于身份为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)

OFH最初为0



我可以获得特定人员的总金额,但我无法使用限制来获取最后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)

这不起作用。

我尝试使用multi-table updatesnested queries来实现这一目标。 每种情况都有已知的局限性阻碍我完成预期的结果。

  • 嵌套查询无法查看父表。 Unknown column 'SV.hid'in 'where clause'
  • 多表更新无法使用限制。 Incorrect usage of UPDATE and LIMIT

任何解决方案都可以。没有必要在单个查询中执行此操作。如果有人想尝试使用中间表。

SQL fiddle也可用。

提前感谢您的帮助。

- 更新 -

以下是Akash的解决方案:http://sqlfiddle.com/#!2/4cf1a/1

4 个答案:

答案 0 :(得分:3)

这应该有效,

更新以加入svice

UPDATE
svice SV
JOIN (
  SELECT 
    hid,
    start,
    sum(degrees) as degrees
  FROM 
    (
      SELECT 
        *,
        IF(@prev_row <> unix_timestamp(start)+P_ID, @row_number:=0,NULL),
        @prev_row:=unix_timestamp(start)+P_ID,
        @row_number:=@row_number+1 as row_number
      FROM 
        (
        SELECT
          mo_date,
          p_id,
          hid,
          start,
          degrees
        FROM 
          OVERW 
          JOIN svice sv ON ( p_id = hid 
                            AND date(mo_date)<date(SV.start) 
                            AND year(mo_date)=year(SV.start) )
         ORDER BY
          hid,
          start,
          mo_date desc
        ) sub_query1
        JOIN ( select @row_number:=0, @prev_row:=0 ) sub_query2
      ) sub_query
    where
      row_number <= 3
    GROUP BY 
      hid,
      start
  ) sub_query ON ( sub_query.hid = sv.hid AND sub_query.start = sv.start )
SET 
  SV.ofh = sub_query.degrees

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

答案 1 :(得分:2)

尝试

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 

http://sqlfiddle.com/#!2/95b42/42

越来越近了,现在它“仅”需要GROUP BY中的限制。

答案 2 :(得分:0)

两个假设:

  1. 您可以弄清楚如何将其转换为更新,
  2. PK存在于(id,mo_date)
  3. 然后你可以这样做 -

    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;
    

答案 3 :(得分:0)

也许我很慢,但现在让我们忽视服务。 你能否在下面的每一行显示正确的结果和工作......

+------+---------+------------+--------+
| 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 |      ? |  
+------+---------+------------+--------+