2011-02-02 4 views
1

이 구문에 대한 적절한 구문을 사용하여 머리를 감쌀 수 없습니다. 다음은 내 하위 쿼리에 대한 간단한 영어 설명과 함께 내 쿼리를 실행하는 곳에서 생각하고있는 곳입니다.MySQL INSERT/SELECT 하위 쿼리 구문

mysql_query("INSERT INTO donations(
      tid, 
      email, 
      amount, 
      ogrequest, 
      total 
      ) 
      VALUES (
       '".esc($p->ipn_data['txn_id'])."', 
       '".esc($p->ipn_data['pay_email'])."', 
       ".(float)$amount.", 
       '".esc(http_build_query($_POST))."', 

      Here I want to select the row with the max date, get the value of the "total" column in that row, and add $amount to that value to form the new "total" for my newly inserted row. 

      )"); 

누구든지 도움을 줄 수 있습니까?

답변

3

진짜 대답은 당신이이 테이블의 열 총을 저장하지 않아야합니다. 실제로 유용한 정보는 아닙니다. 저장해야하는 것은 현재 날짜이며 SUM 및 GROUP BY를 통해 합계를 계산하는 것입니다. 자주 액세스해야하는 것이면 그 값을 다른 곳에 캐시하십시오.

왜 마지막 행보다 이전에 합계가 필요합니까? 낭비되는 데이터 일 뿐이며 테이블에서 쉽게 재생성 될 수 있습니다.

왜이 열에 총계를 저장 하시겠습니까? 이 데이터는 스키마에 어떤 가치를 부여합니까? 여기에서 주목해야 할 중요한 점은 총액이 개별 거래의 속성이 아니라는 것입니다. 합계는 개별 트랜잭션의 집계 된 하위 집합의 속성입니다.

또한, DECIMAL을 사용하고 MySQL의 통화 열 유형에 FLOAT를 사용하고 있지 않은지 확인하십시오. FLOAT 값은 수행중인 작업에 따라 반올림 오류가 발생할 수 있습니다. 이는 돈이 관련 될 때 위험 할 이유가 없습니다.

+0

네가 맞아. 내가 그것을하고있는 유일한 이유는 자주 액세스해야하기 때문에 SUM을 계속해서 여러 번 계산하는 오버 헤드에 대해 궁금해하고있었습니다. 나는 모든 행을 거치지 않고 대신 마지막 행에서 단일 값을 얻을 수 있다는 것을 알았습니다. 그러면 DB에 덜 부담이 될 것입니다. 캐싱에 어떤 기술을 권하고 싶습니까? – Jon

+0

MySQL을 캐쉬 할 가능성이 있기 때문에 이것을 캐쉬 할 필요는 거의 없습니다. 대형 응용 프로그램에서이 작업을 수행하는 일반적인 방법은 memcached (http : // memcached)와 같은 것을 사용하는 것입니다.org /). 그러나 이것을 배울 필요가 없다면 기부 테이블의 트리거를 통해 업데이트되는 다른 mysql 테이블에 값을 저장하는 것으로 벗어날 수 있습니다. – schizodactyl

+0

나는이 길로 갈거야. 조언을 주셔서 감사합니다, 그리고 다른 사람들의 답변을 ... 그들은 많이 감사합니다. – Jon

0

나는 내가 만든 것을 확인하는 MySQL 서버에 액세스 할 수 있지만하지 않는이 :

INSERT INTO donations 
(
    tid, 
    email, 
    amount, 
    ogrequest, 
    total 
) 
SELECT 
    '".esc($p->ipn_data['txn_id'])."', 
    '".esc($p->ipn_data['pay_email'])."', 
    ".(float)$amount.", 
    '".esc(http_build_query($_POST))."', 
    total + '".esc($amount)."' 
FROM 
ORDER BY date DESC 
LIMIT 1 

사용하는 대신 직접 "INSERT INTO (...) VALUES (...) ""INSERT INTO (...) SELECT ... "를 사용했습니다. SELECT 문은 날짜가 가장 높은 행 (ORDER BY 날짜 DESC LIMIT 1)을 검색 한 다음 총 필드에 액세스하고 $ amount 값을 추가합니다.

0
mysql_query("INSERT INTO donations(
      tid, 
      email, 
      amount, 
      ogrequest, 
      total 
      ) 
      VALUES (
       '".esc($p->ipn_data['txn_id'])."', 
       '".esc($p->ipn_data['pay_email'])."', 
       ".(float)$amount.", 
       '".esc(http_build_query($_POST))."', 
       (select max(total) from donations) + ".(float)$amount." 




      )"); 
0

귀하의 하위 쿼리는 다음과 같이 수 : 물론

SELECT total 
FROM donations 
WHERE tid = <x> 
ORDER BY date DESC 
LIMIT 1 

이 당신이 당신의 테이블에 date 열이 있어야합니다

. 이 쿼리를 이미 실행 한 외부 쿼리없이 실행하면 tid = <x>의 최신 총 값을 포함하는 단일 행 결과가 반환됩니다.

테이블에 아직 txn = <x>의 행이 없으면 명백히 전혀 행을 반환하지 않습니다. INSERT 문의 하위 쿼리로 사용하는 경우 NULL을 확인하고 숫자 0으로 대체해야합니다. 이것은 IFNULL()이 당신을 위해 할 수있는 것입니다.

이 결합하고 당신이 이미 가지고있는 :

mysql_query("INSERT INTO donations(
      tid, 
      email, 
      amount, 
      ogrequest, 
      total 
      ) 
      VALUES (
       '".esc($p->ipn_data['txn_id'])."', 
       '".esc($p->ipn_data['pay_email'])."', 
       ".(float)$amount.", 
       '".esc(http_build_query($_POST))."', 
       IFNULL(SELECT total 
       FROM donations 
       WHERE id = ".esc(p->ipn_data[txn_id']." 
       ORDER BY date DESC 
       LIMIT 1),0) + ".esc($p->ipn_data['value'] 
      )");