MarissaReloaded Ответов: 2

Нужна помощь с SQL запросом с сообщением об ошибке подзапрос возвращает более 1 строки


I have two tables, and I would like to update the running balance of expenses by retrieving the allocation(budget) based on matching voteid

I'm using phpmyadmin mysql 

* Apache/2.4.43 (Win64) OpenSSL/1.1.1g PHP/7.4.6
* Database client version: libmysql - mysqlnd 7.4.6
* PHP extension: mysqli Documentation curl Documentation mbstring Documentation
* PHP version: 7.4.6
* Server type: MariaDB


Table 1

| voteid | allocation |
+--------+------------+
| 1      | 50000      |
| 2      | 10000      |
| 3      | 34000      |
| 4      | 70000      |
Table 2

    | expenditureid | voteid | expenses |
    +---------------+--------+----------+
    | 1             | 2      | 300      |
    | 2             | 2      | 650      |
    | 3             | 4      | 900      |
    | 4             | 4      | 1200     |
    | 5             | 3      | 34000    |
Expected result

+---------------+--------+----------+------------------------------+-----------------------------------------------------+
| expenditureid | voteid | expenses | balance (running difference) | calculation |
+---------------+--------+----------+------------------------------+-----------------------------------------------------+
|               |        |          |                              | 10000                                               |
+---------------+--------+----------+------------------------------+-----------------------------------------------------+
| 1             | 2      | 300      | 9700                         | (10000-300)                                        |
+---------------+--------+----------+------------------------------+-----------------------------------------------------+
| 2             | 2      | 650      | 9050                         | (9700-650)                                          |
+---------------+--------+----------+------------------------------+-----------------------------------------------------+
|               |        |          |                              |                                                     |
+---------------+--------+----------+------------------------------+-----------------------------------------------------+
|               |        |          |                              | 70000                                               |
+---------------+--------+----------+------------------------------+-----------------------------------------------------+
| 3             | 4      | 900      | 69100                        | (70000-900)                                         |
+---------------+--------+----------+------------------------------+-----------------------------------------------------+
| 4             | 4      | 1200     | 67900                        | (69100-1200)                                        |
+---------------+--------+----------+------------------------------+-----------------------------------------------------+
|               |        |          |                              |                                                     |
+---------------+--------+----------+------------------------------+-----------------------------------------------------+
|               |        |          |                              | 34000                                               |
+---------------+--------+----------+------------------------------+-----------------------------------------------------+
| 5             | 3      | 4000     | 30000                        | (34000-4000)                                        |
+---------------+--------+----------+------------------------------+-----------------------------------------------------+


Что я уже пробовал:

SELECT allocation 
FROM vote 
INNER JOIN expenditure ON vote.voteid = expenditure.voteid 
GROUP BY vote.voteid;

SET @csum = (SELECT allocation 
             FROM vote 
             INNER JOIN expenditure ON vote.voteid = expenditure.voteid 
             GROUP BY vote.voteid);

UPDATE expenditure 
SET balance = (@csum = @csum - expenses) OVER (partition BY voteid ORDER BY expenditureid) AS balance;

2 Ответов

Рейтинг:
1

Herman<T>.Instance

Часть запроса

SET @csum = (SELECT allocation 
             FROM vote 
             INNER JOIN expenditure ON vote.voteid = expenditure.voteid 
             GROUP BY vote.voteid);

вернет mpre более 1 строки.

Вы должны уточнить это утверждение, чтобы у вас было максимум 1 строка.
Другой вариант-использовать предложение IN для обработки нескольких строк


MarissaReloaded

Привет, спасибо за ваши отзывы
Не могли бы вы привести пример?

Рейтинг:
0

Jörgen Andersson

Вы мыслите процедурно.
С SQL лучше всего думать в наборах.
И вы также должны рассмотреть возможность нормализации данных, поэтому необходимость обновления баланса-это плохая идея, которую следует запрашивать при необходимости. Нормализация базы данных - Википедия[^]

Взгляните на следующий запрос и скорректируйте его по мере необходимости:

SELECT  voteid
       ,allocation
       ,SUM(expenses) AS expenses
       ,allocation - SUM(expenses) AS Balance
FROM    vote 
JOIN    expenditure ON vote.voteid = expenditure.voteid
GROUP BY voteid,allocation