我有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 updates
和nested queries
来实现这一目标。
每种情况都有已知的局限性阻碍我完成预期的结果。
Unknown column 'SV.hid'in 'where clause'
Incorrect usage of UPDATE and LIMIT
任何解决方案都可以。没有必要在单个查询中执行此操作。如果有人想尝试使用中间表。
SQL fiddle也可用。
提前感谢您的帮助。
- 更新 -
以下是Akash的解决方案:http://sqlfiddle.com/#!2/4cf1a/1
答案 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)
两个假设:
然后你可以这样做 -
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 | ? |
+------+---------+------------+--------+