2014-02-18 4 views
0

SELECT에서 각 행에 대한 추가 쿼리 (UPDATE)를 실행하는 방법은 무엇입니까? select에서 각 행의 금액을 가져와 사용자의 잔액 테이블로 보내야합니다.SELECT 쿼리의 각 행에 대한 연산

예 :

status 0 - open 
status 1 - processed 
status 2 - closed 

내 선택 문 : 시장 테이블

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 

에서

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; 

선택 결과 우리는 (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 

포스트 그레스 버전 9.3

답변

0

일반적인 원리는 하위 쿼리를 통해 UPDATE ... FROM을 사용하는 것입니다. 귀하의 예를 유용 CREATE TABLESELECT 문으로 설정하기에 너무 어렵다, 그래서 나는 빠른 더미 데이터 집합을 만들 었 :

: 당신은 당신이 좋아하는 일을 할 것 잔액에 트랜잭션을 적용하고 싶다면

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은 트랜잭션을 적용된 것으로 표시합니다. 당신은 당신의 디자인에서 그런 것을 필요로하지 않을 수도 있습니다.

관련 문제