2013-08-16 3 views
5

최적화 할 필요가 내가MySQL의 쿼리는

id | productid | userid | coinsid 
1 | 2   | 2  | 5  
3 | 2   | 2  | 6  
4 | 2   | 3  | 7 
5 | 2   | 4  | 8 
6 | 2   | 3  | 9 

이 특정 productid에 대한 결과와 같은 결과를 제공하는 쿼리가 있습니다. 위의 결과에서 모든 사용자에게 $ 1을 추가하여 user table의 잔액을 업데이트해야하지만 userid이 두 번이면 해당 사용자의 잔액에 $ 1을 두 번 추가해야합니다. 그래서 위의 경우 $ 1은 userid=2 잔액과 userid=3 잔액에 두 번 추가되었습니다.

단순한 방법은 각 userid에 대해 레코드를 계산하고 우리는 사용자가 foreach 루프에있는 것처럼 많은 시간 동안 쿼리를 실행하는 것입니다. 그러나 나는 어떤 최적의 방법을 찾고 있습니다. 제안 해주십시오. 감사합니다

+0

userID 및 sum coinsID로 쿼리 결과를 그룹화하십시오. userID의 개수에 대한 열을 추가하십시오. userID의 수를 $ 1로 곱하고 coinsId를 새 값으로 업데이트하십시오. – xQbert

+0

@AliBZ, 예 'balance'는 사용자 테이블의 열 이름입니다. 균형을 업데이트해야하는 곳. –

+0

미안하지만, 나, 그 부분을 놓쳤다. – AliBZ

답변

4

한 가지 방법 :

UPDATE user_table u 
    JOIN (SELECT q.userid 
       , SUM(1.00) AS deposit 
      FROM (
        -- original OP query goes here 
       ) q 
      GROUP BY q.userid 
     ) r 
    ON r.userid = u.userid 
    SET u.balance = u.balance + r.deposit 

우리는 표시되는 결과 집합을 반환 원래 OP 쿼리를 사용하게 그 ( 로 Q 위의 쿼리의 별칭) 인라인보기.

이로부터 우리는 고유 한 userid 목록과 userid가 결과 집합에 나타나는 횟수를 쿼리합니다. 그것은 우리에게 사용자 이름과 예금 금액 (사용자 ID가 나타날 때마다 1 달러)을줍니다 (일부 데이터베이스는 소수가 맞는지 확인하기 위해 값을 1.0이 아닌 1로 지정하기를 원할 수 있습니다.) SUM이

사용자 테이블에 인라인보기 (r)를 결합하고 해당 사용자의 현재 잔액에 입금액을 추가합니다 (잔액이 십진수로 저장되었다고 가정하면 1.00 = 1 달러) 시험으로


가하는 SELECT 문에 UPDATE 변환 :

  • 는 선택 사항 (에 "ORDER BY"절을 추가 "SET"절
  • 을 제거)을 만들 수 결과 확정
  • "UPDATE"키워드를 제거하고 바꾸십시오.

과 : 선택 전체

SELECT r.userid 
     , r.deposit 
     , u.balance    AS old_balance 
     , u.balance + r.deposit AS new_balance 
     , u.userid 
    FROM 

:

SELECT r.userid 
     , r.deposit 
     , u.balance    AS old_balance 
     , u.balance + r.deposit AS new_balance 
     , u.userid 
    FROM user_table u 
    JOIN (SELECT q.userid 
       , SUM(1.00) AS deposit 
      FROM (
        -- original OP query goes here 
       ) q 
      GROUP BY q.userid 
     ) r 
    ON r.userid = u.userid 

참고 절, 행이 선택되어 결정 무엇인가 (ON 절에) 조건을 가입 위치에 상관 없다/사용자 테이블에서 영향을받습니다.

+0

(이전에 조인 기준이 누락되었습니다 ... DOH! fixed. – spencer7593

+0

답장을 보내 주셔서 감사합니다. 불행히도 모든 사용자에 대해 균형을 업데이트했지만, 업데이트 쿼리 끝에 where 절이 필요합니까? –

+0

이제 완벽하게 일했습니다. 여러 사용자들에게 시도하겠습니다 :) –

0
select count(*), userid from yourTable group by userid 

만약 당신의 질문을 이해하십시오. 내가 PLSQL 더 잘 알고로

update balance_table set balance_table.balance = (select count(*) from users_table where users_table.user_id = balance_table.user_id) * 1; 

내가 MySQL 데이터베이스에 대해이 쿼리를 시도하지 않은,하지만 :

1

당신이 당신의 균형 테이블에 중복 된 사용자 ID가없는 가정 할 때,이 같은 아마 뭔가 일 것 이 일은 좋아하지 않을거야?

+0

이 경우 * 1은 사용자 당 1 $를 추가하려고하지만 어떤 금액으로 변경 될 수 있기 때문입니다. – schwarz

+0

여러 명의 사용자 ID가 중복되지 않으므로 작동하지 않을 것입니다. –

1

다른 대답의 상관 된 하위 쿼리가 작동하지만 일반적으로 INNER JOIN이 더 효율적입니다. 이런 식으로 해보십시오. 물론 테이블과 컬럼 이름을 제공해야 할 것이다.

UPDATE myTable 
INNER JOIN (
    SELECT userid, count(*) AS AmountToAdd 
    FROM users 
    GROUP BY userid 
) UserCounts ON myTable.userid = UserCounts.userid 
SET balance = balance + UserCounts.AmountToAdd 
+0

이것은 유용한 방법입니다. 그러나이 쿼리의 인라인 뷰는'FROM users'이지만 OP는 사용자 목록이 쿼리의 결과임을 나타 냈습니다. (쿼리의 실제 텍스트는 제공되지 않았습니다.) 따라서 OP는'FROM users'를 대체해야합니다. FROM (SELECT/* original query * /) 별칭'을 사용합니다. 쿼리에서 참조되는 테이블이 둘 이상인 경우 모범 사례는 모든 열 참조를 한정하는 것입니다. – spencer7593