Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 使带有联接的更新应用于所有记录_Mysql - Fatal编程技术网

Mysql 使带有联接的更新应用于所有记录

Mysql 使带有联接的更新应用于所有记录,mysql,Mysql,我有三张桌子: TABLE bon TABLE order TABLE payed b_id | total | payed | diff id | b_id | amm id | b_id | amm -----+-------+-------+------ ---+------+----- ---+------+----- 1 | 0 | 0 | 0 1 |

我有三张桌子:

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)
遗憾的是,这不会更新任何行。那么我在这件事上错在哪里呢


编辑:我找到了一个解决方案,并将其发布在下面。我不知道这是否是最好的方法,但它有效。建议仍然受欢迎。

虽然我还没有找到解决方案,但我认为您的第二个查询存在一些问题

1让我们看看您的第一个内部查询:

SELECT
`b_id`,
SUM(`amm`) AS `total`
FROM `order` 
首先,这将从顺序中提取所有行,但是您的计算列(别名为total)在每一行中的值都相同

这可能不是你想要的。将该SELECT中的结果集与bon表连接并不意味着MySQL会在幕后应用一些魔法,并将连接中使用的列所产生的结果集分组

相反,首先生成表bon的叉积和第一个SELECT的结果集。该叉积在每行中的total值也相同。然后联接只过滤bin.b_id和s1.b_id相同的行

当然,这些行中的每一行仍然具有相同的总值,因此即使它进行了更新,也会得到错误的结果

补救办法是在SELECT语句中添加一个按b_id分组的语句。这将导致正确计算总数,即每个b_id。然后将使用分组的b_id进行连接

这同样适用于第二个SELECT内部查询

2您正在使用SELECT from表格payed进行内部联接。这意味着结果将不包含任何未在payed中的行。对于示例数据,结果将不包含b_id为1的行,因为付款表不包含此类行

这个问题不是那么容易解决的。一种解决方案是在运行查询之前确保payed表中有每个b_id。但是,当支付表中不存在的ID没有更新时,您可能会感到高兴


如果你能更详细地描述一下你想要什么,我们最终可以找到一个解决方案。

我找到了一个解决方案,跳过了所有的连接。也许不是最好的答案,但它是有效的建议仍然是受欢迎的:

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`
            )

谢谢你的详细回答。我只想用其他两个表中相应值的总和来更新bon。对于每个b_id,总是至少有一个条目,但在payed中,它可能会丢失。我玩了各种各样的游戏,都没用。我找到了一个解决办法,放弃了所有的连接。我不知道这是否是最好的,但它确实有效。