如何在SELECT的每一行上执行附加查询(UPDATE)? 我必须从select中获取每行的金额并将其发送到用户的余额表。
示例:
status 0 - open
status 1 - processed
status 2 - closed
我的选择陈述:
select id, user_id, sell_amount, sell_currency_id
from (select id, user_id, sell_amount, sell_currency_id,
sum(sell_amount)
over (order by buy_amount/sell_amount ASC, date_add ASC) as cumsell
from market t
where (status = 0 or status = 1) and type = 0
) t
where 0 <= cumsell and 7 > cumsell - sell_amount;
从市场表中选择结果
id;user_id;amount;status
4;1;1.00000000;0
6;2;2.60000000;0
5;3;2.00000000;0
7;4;4.00000000;0
我们得到7金额并将其发送到用户余额表。
id;user_id;amount;status
4;1;0.00000000;2 -- took 1, sum 1, status changed to 2
6;2;0.00000000;2 -- took 2.6, sum=3.6, status changed to 2
5;3;0.00000000;2 -- took 2, sum 5.6, status changed to 2
7;4;2.60000000;1 -- took 1.4, sum 7.0, status changed to 1 (because there left 2.6 to close)
用户余额表
user_id;balance
5;7 -- added 7 from previous operation
Postgres版本9.3
答案 0 :(得分:0)
一般原则是在子查询上使用UPDATE ... FROM
。您的示例太难转变为有用的CREATE TABLE
和SELECT
语句,因此我编写了一个快速虚拟数据集:
CREATE TABLE balances (user_id integer, balance numeric);
INSERT INTO balances (user_id, balance) VALUES (1,0), (2, 2.1), (3, 99);
CREATE TABLE transactions (user_id integer, amount numeric, applied boolean default 'f');
INSERT INTO transactions (user_id, amount) VALUES (1, 22), (1, 10), (2, -10), (4, 1000000);
如果您想将交易应用于余额,您可以执行以下操作:
BEGIN;
LOCK TABLE balances IN EXCLUSIVE MODE;
LOCK TABLE transactions IN EXCLUSIVE MODE;
UPDATE balances SET balance = balance + t.amount
FROM (
SELECT t2.user_id, sum(t2.amount) AS amount
FROM transactions t2
GROUP BY t2.user_id
) t
WHERE balances.user_id = t.user_id;
UPDATE transactions
SET applied = true
FROM balances b
WHERE transactions.user_id = b.user_id;
LOCK
语句对于存在并发插入/更新的正确性非常重要。
第二个UPDATE
标记所应用的交易;在设计中你可能不需要这样的东西。