MySQL запрос превращается без изменений в 0 - PullRequest
0 голосов
/ 19 октября 2018

Это простой запрос, который при выполнении обновляет денежные средства, имеющиеся у некоторых пользователей, когда им причитаются ссуды:

$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 голосов
/ 19 октября 2018

Ваш запрос UPDATE не имеет критериев, ограничивающих область обновления только теми, на которые влияет due_date.

Кроме того, поскольку вы не используете функцию агрегирования в таблице ссуд, MySQLсвободно выбирать любое значение из тех, которые были сгруппированы.Это может привести к неожиданным результатам.

Чтобы решить эту проблему, вы можете изменить подзапрос SET на JOIN.Это предотвратит несогласованные записи из таблицы ссуд от обновления таблицы соревнований с нулями.А также уменьшите количество запросов, которые могут возникнуть, поскольку использование подзапроса в 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 |

Thisсначала извлекает значения competitions_id и due_amount из таблицы ссуд, на которые влияют due_date.

Обновления базовой таблицы competitions затем ограничиваются INNER JOIN, который включаеттолько записи, совпадающие с записями в таблице ссуд.

Я использовал SUM в качестве агрегатной функции, чтобы гарантировать, что все due_amount записей по всем ссудам для Competitions_id суммируются.Это похоже на то, что вы намеревались, если нет, и вы хотите один due_amount, запрос может быть изменен в соответствии с желаемыми результатами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...