我有3张桌子:
TABLE bon TABLE order TABLE payed
b_id | total | payed | diff id | b_id | amm id | b_id | amm
-----+-------+-------+------ ---+------+----- ---+------+-----
1 | 0 | 0 | 0 1 | 1 | 5 1 | 2 | -10
-----+-------+-------+------ ---+------+----- ---+------+-----
2 | 0 | 0 | 0 2 | 2 | 5 2 | 3 | -5
-----+-------+-------+------ ---+------+----- ---+------+-----
3 | 0 | 0 | 0 3 | 1 | 15
---+------+-----
4 | 3 | 10
---+------+-----
5 | 2 | 15
---+------+-----
6 | 2 | 20
如果我想仅为一个ID更新 bon 中的总计,我会这样做:
UPDATE `bon`
INNER JOIN (
SELECT
SUM(`amm`) AS `total`
FROM `order`
WHERE `b_id`=2
) AS s1
INNER JOIN (
SELECT
COALESCE(SUM(`amm`),0) AS `payed`
FROM `payed`
WHERE `b_id`=2
) AS s2
SET
`bon`.`total` = s1.`total`,
`bon`.`payed` = s2.`payed`,
`bon`.`diff` = s1.`total` + s2.`payed`
WHERE `b_id`=2;
将 id 2 正确更新为
b_id | total | payed | diff
-----+-------+-------+------
2 | 40 | -10 | 30
但是,我尝试使用以下内容更新所有 ID
UPDATE `bon`
INNER JOIN (
SELECT
`b_id`,
SUM(`amm`) AS `total`
FROM `order`
) AS s1 ON bon.`b_id`=s1.`b_id`
INNER JOIN (
SELECT
`b_id`,
SUM(`amm`) AS `payed`
FROM `payed`
) AS s2 ON bon.`b_id`=s2.`b_id`
SET
`bon`.`total` = s1.`total`,
`bon`.`payed` = COALESCE(s2.`payed`,0),
`bon`.`diff` = s1.`total` + COALESCE(s2.`payed`,0)
可悲的是,这不会更新任何行。那我在哪里错了?
编辑:我找到了解决方案并将其发布在下方。不知道这是否是最好的方法,但它有效(建议仍然欢迎)。
答案 0 :(得分:1)
虽然我还没有找到解决方案,但我认为您的第二个查询存在一些问题。
1)让我们看看你的第一个内部查询:
SELECT
`b_id`,
SUM(`amm`) AS `total`
FROM `order`
首先,这将从order
中提取所有行,但是您将其别名为total
的计算列将在每个中包含相同的值行
这可能不是你想要的。将SELECT
的结果集与bon
表连接起来 not 意味着MySQL会在幕后使用一些魔法,并在列中使用的结果组中使用JOIN
。
相反,首先构建表bon
中的叉积和第一个SELECT
的结果集(此叉积也具有{em>相同的值{每行{1}}。 total
只会过滤JOIN
和bin.b_id
相同的行。
当然,这些行中的每一行仍然具有相同的s1.b_id
值,因此即使进行了更新,也会得到错误的结果。
补救措施是在total
语句中添加b_id
分组。这将导致SELECT
被正确计算,即每total
。然后,您可以使用分组 b_id
作为b_id
。
这同样适用于您的第二个JOIN
内部查询。
2)您正在使用表格SELECT
中的INNER JOIN
进行SELECT
。这意味着结果将不包含任何不在payed
中的行。使用示例数据,结果将不包含payed
为b_id
的行(因为您的1
表不包含此类行。)
这个问题并不容易解决。一种解决方案是在运行查询之前确保payed
表中的每个b_id
。但是,如果payed
表中不存在的ID未更新,您可能会感到高兴。
如果您更详细地描述您想要的内容,我们最终可以找到解决方案。
答案 1 :(得分:0)
我找到了一个解决方案,跳过了所有的JOINS。也许不是最好的答案,但它有效(建议仍然欢迎):
UPDATE `bon`
SET
`bon`.`total` =
(SELECT
COALESCE(SUM(`amm`),0)
FROM `order`
WHERE `order`.`b_id`=`bon`.`b_id`
),
`bon`.`payed` =
(SELECT
COALESCE(SUM(`amm`),0)
FROM `payed`
WHERE `payed`.`b_id`=`bon`.`b_id`
),
`bon`.`diff` =
(SELECT
COALESCE(SUM(`amm`),0)
FROM `order`
WHERE `order`.`b_id`=`bon`.`b_id`
)+
(SELECT
COALESCE(SUM(`amm`),0)
FROM `payed`
WHERE `payed`.`b_id`=`bon`.`b_id`
)