我有一个具有以下结构的mysql表
id name_id class_id currency date value change
1 BILL A 0 04-01-2013 10.00 0
5 BILL A 0 04-02-2013 9.90 0
12 FRED A 0 04-01-2013 8.00 0
13 FRED B 1 04-02-2013 8.50 0
22 FRED B 1 04-03-2013 8.51 0
我希望在change
,name_id
和class_id
相等时,根据当天的值与上一个日期值之间的差异更新currency
列。 。 。所以在这个小摘录中,只有第2行会更新为-0.10
,第5行会更新为0.01
。
有400,000行,它们都具有自动递增的ID,但ID不是任何类型的顺序。缺少周末和假日日期,因此没有连续日期。
我似乎能够通过像这样的查询显示更改
SELECT pd.name_id,
pd.class_id,
pd.currency,
pd.date,
pd.value,
ROUND(pd.nav - (SELECT nav
FROM price_data as x
WHERE x.date < pd.date
AND x.name_id = pd.name_id
AND x.class_id = pd.class_id
AND x.currency = pd.currency
ORDER BY price_date DESC
LIMIT 1),5) as change
FROM price_data as pd
我已经尝试修改它来进行更新,但我不断收到一条说#1093 - You can't specify target table 'pd' for update in FROM clause
的mysql错误,即便如此我也不确定这是正确的做法。使用php会更容易吗?
UPDATE price_data as pd
SET pd.change = (
pd.value - (SELECT value
FROM price_data as x
WHERE x.date < pd.date
AND x.fund_id = pd.fund_id
AND x.class_id = pd.class_id
AND x.currency = pd.currency )
)
感谢您提供的任何帮助。
答案 0 :(得分:0)
你的任务并不容易。所以,我决定将它分成2个请求:1个SELECT和1个UPDATE。
代码是用php制作的,基于数据,你在小提琴中提供:
<?php
try {
$username = 'user';
$password = '';
$conn = new PDO('mysql:host=localhost;dbname=test', $username, $password);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $conn->prepare('
SELECT pd.id,
ROUND(pd.value - (SELECT value
FROM price_data as x
WHERE x.price_date < pd.price_date
AND x.fund_id = pd.fund_id
AND x.class_id = pd.class_id
AND x.currency_id = pd.currency_id
ORDER BY x.price_date DESC
LIMIT 1
),5) as `change`
FROM price_data as pd
WHERE
pd.`value_change`=0
');
$stmt->execute();
$result = array();
while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
if (!is_null($row["change"]))
{
var_dump($row);
$stmt2 = $conn->prepare('
UPDATE
price_data
SET
price_data.value_change=:change
WHERE
price_data.id=:id
');
$stmt2->execute($row);
}
}
} catch(PDOException $e) {
echo 'ERROR: ' . $e->getMessage();
}
?>
这更新了我机器上的必要记录。请告诉我,它对您的影响如何。