MySQL查询变为不受影响的0

时间:2018-10-19 14:23:39

标签: php mysql database

这是一个简单的查询,当执行该查询时,会更新某些用户到期的可用现金:

$sqlx = "UPDATE competitions
    SET cash = (SELECT cash_after_deduct 
                FROM (SELECT l.competitions_id, 
                             (c.cash-l.due_amount) AS cash_after_deduct
                      FROM loans l
                      JOIN competitions c ON l.competitions_id = c.id
                      WHERE l.due_date='2018-10-28'
                      GROUP BY l.competitions_id) q1
                WHERE q1.competitions_id = competitions.id
    )
";

应在2018-10-28上借贷的那些用户的现金行。它有效;但是,到期日期不同的用户中的现金行将重置为0,而这些行应保持不变。

有什么问题的想法吗?

非常感谢。

1 个答案:

答案 0 :(得分:0)

您的UPDATE查询没有条件将更新范围限制为仅受due_date影响的那些。

另外,由于您不在借贷表上使用汇总函数,因此MySQL可以自由选择分组值中的任何单个值。这可能会导致意外结果。

要解决此问题,您可以将SET子查询更改为JOIN。这将防止来自贷款表的不匹配记录将竞争表更新为0。由于减少了将要发生的查询的数量,因为在SET中使用子查询将要求为每个记录发出一个查询,以匹配正在按set更新的竞赛中的当前行。

示例:http://sqlfiddle.com/#!9/2a2c147/1

UPDATE competitions AS c
INNER JOIN (
    SELECT l.competitions_id, SUM(l.due_amount) AS total_due
    FROM loans AS l
    WHERE l.due_date = '2018-10-28'     
    GROUP BY l.competitions_id
    #optionally limit scope to those that have an amount due
    #HAVING total_due > 0
) AS d
ON d.competitions_id = c.id
SET c.cash = c.cash - d.total_due

数据集

competitions
---
| id  | cash | 
|-----|------| 
| 1   | 5.00 | 
| 2   | 2.00 | 
| 3   | 0.00 | 
loans
---
| id | competitions_id | due_amount |   due_date | 
|----|-----------------|------------|------------| 
| 1  |               1 |       1.00 | 2018-10-19 | 
| 2  |               1 |       1.00 | 2018-10-28 | 
| 3  |               2 |       1.00 | 2018-10-28 | 
| 4  |               1 |       1.00 | 2018-10-28 | 
| 5  |               3 |       1.00 | 2018-11-19 | 

结果

| id | cash | total_due | cash_after_deduction | loan_deductions |
|----|------|-----------|----------------------|-----------------|
|  1 |    5 |         2 |                    3 |               2 |
|  2 |    2 |         1 |                    1 |               1 |

这是通过首先从受competitions_id影响的贷款表中检索due_amountdue_date的值来实现的。

然后,competitions将限制基本INNER JOIN表的更新,SUM仅包含与借贷表中找到的记录匹配的记录。

我使用due_amount作为汇总函数,以确保对来自Competitions_id的所有贷款中的所有due_amount条记录进行汇总。 这看起来像您想要的,如果没有,并且您想要一个BtnRemoveAdmin,则可以修改查询以匹配所需的结果。