2012-01-01 3 views
3

지정된 값보다 크거나 작은 행에 누적 합계가있는 행을 반환하는 방법은 무엇입니까?쿼리에서 누적 합계

테이블 :

id | count 
----------- 
1 | 30 
2 | 10 
3 | 5 
4 | 20 
5 | 15 

쿼리 :

SELECT id, count 
FROM table 
ORDER BY id 
HAVING SUM(count) < 50 

반환 행 :

id | count 
------------- 
1 | 30 
2 | 10 
3 | 5 

갱신

코드 :

public function query(){ 
    switch($this->table){ 
     case 'in_stock': 
      return "SELECT * FROM ".Init::$static['db'].".stock 
       WHERE id<=dynaccount.stock_first_available_id(".$this->value['num_stock'].", ".$this->value['product_id'].", ".(isset($this->att_arr['gid']) ? $this->att_arr['gid']:$_SESSION['gid']).") 
       ORDER BY time, id"; 
    } 
} 

절차 :

DELIMITER $$ 

DROP FUNCTION IF EXISTS `stock_first_available_id` $$ 
CREATE DEFINER=`dynaccount`@`localhost` FUNCTION `stock_first_available_id`(_running_total_limit INT, _product_id INT, _group_id INT) RETURNS INT 
BEGIN 
    DECLARE _running_count INT default 0; 
    DECLARE _id INT; 
    DECLARE _current_id INT; 
    DECLARE _sum_count INT; 

    IF (SELECT COUNT(*) FROM stock WHERE group_id=_group_id && type=2 && product_id=_product_id) = 0 THEN 
     RETURN 0; 
    END IF; 

    DECLARE _cur CURSOR FOR SELECT id, count FROM stock WHERE group_id=_group_id && type=2 && product_id=_product_id ORDER BY time DESC, id DESC; 

    OPEN _cur; 

    read_loop: LOOP 
     FETCH _cur INTO _id, _sum_count; 

     SET _running_count = _running_count + _sum_count; 
     SET _current_id = _id; 

     IF _running_count > _running_total_limit THEN 
      LEAVE read_loop; 
     END IF; 
    END LOOP read_loop; 

    CLOSE _cur; 

    RETURN _current_id; 
END $$ 

DELIMITER ; 

오류 :

#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'DECLARE _cur CURSOR FOR SELECT id, count FROM stock WHERE group_id=_group_id &amp;&amp; ' at line 12 
+0

가 : 반환

SELECT * FROM sumtest WHERE id <= Test_Cursing(50); 

: 당신은이를 사용할 수 있습니까? –

+0

@ 뮤, 너 무슨 뜻이야? mysql에서 할 수 없는가? – clarkk

+0

http://stackoverflow.com/questions/1135627/mysql-select-accumulated-column을 살펴보십시오. 누적 합계가 전체보다 적은 모든 행을 선택할 수 있습니다. – dash

답변

6

다음 쿼리 :

SELECT * FROM 
(SELECT id, 
     count, 
     @running_count := @running_count + count AS Counter 
    FROM sumtest, (SELECT @running_count := 0) AS T1 ORDER BY id) AS TableCount 

WHERE TableCount.Counter < 50; 

작성된 결과 :

id count Counter 
1 30  30 
2 10  40 
3 5  45 

테이블을 MySql에 복사하고 "sumtest"btw라고했습니다. 테이블 이름으로 바꾸십시오.

사실상 누적 합계를 ID 순서대로 계산 한 다음이를 하위 쿼리로 사용합니다.

그래서이 쿼리 :

SELECT id, 
     count, 
     @running_count := @running_count + count AS Counter 
FROM sumtest, (SELECT @running_count := 0) AS T1 
ORDER BY id 

는 생산 :

id count Counter 
1 30  30 
2 10  40 
3 5  45 
4 20  65 
5 15  80 

를 그럼이 카운터가 서로를 수행하여 원하는 합보다 작은 위치를 선택을 모든 행에 선택 사소한 문제가된다 이.

편집 : 다음은 커서가있는 예입니다. 나는 당신을 위해 함께이 기능을 발생했습니다 (내 표를 참고 sumtest라고 내 계정이 기본 루트 @ 로컬 호스트입니다) :

DELIMITER $$ 

DROP FUNCTION IF EXISTS `Test_Cursing` $$ 
CREATE DEFINER=`root`@`localhost` FUNCTION `Test_Cursing`(_running_total_limit INT) RETURNS int 
BEGIN 
    /* Why am I on StackOverflow at 01:41 on New Years Day. Dear oh dear, where's the beer? */ 
    DECLARE _running_count INT default 0; 
    DECLARE _id INT; 
    DECLARE _current_id INT; 
    DECLARE _sum_count INT; 

    DECLARE _cur CURSOR FOR SELECT id, count FROM sumtest ORDER BY id; 

    OPEN _cur; 

    read_loop: LOOP 
    FETCH _cur INTO _id, _sum_count; 

    SET _running_count = _running_count + _sum_count; 

    IF _running_count > _running_total_limit THEN 
     LEAVE read_loop; 
    END IF; 

    SET _current_id = _id; 

    END LOOP; 

    CLOSE _cur; 

    RETURN _current_id; 

END $$ 

DELIMITER ; 

이런 식 호출 :

SELECT Test_Cursing(50); 

이 ID를 반환됩니다 = 3 - 실행중인 총 한도가 초과되기 전의 마지막 ID입니다. MySQL이 유일한 옵션

id count 
1 30 
2 10 
3 5 
+0

은 그것을 테스트하지 않았지만 모든 선택과 함께 비효율적이지 않습니까? 그것은 3 개의 선택으로 끝날 것입니다 – clarkk

+0

에 따라 다릅니다. 테이블이 매우 크면 실행중인 총계에서 성능 저하를 볼 수 있지만 테스트해야합니다 (예 : EXPLAIN 키워드 사용). select @running_count : = 0과 outer select는 사소한 것이므로 비교할 때 어떤 영향도 주어서는 안됩니다. 반면에 원하는 총계에 도달하면 바로 종료 할 수있는 커서를 사용할 수 있습니다. SqlDataReader (C#을 아는 사람이라면)에서도 코드를 수행하는 것이 간단하고 효율적입니다. – dash

+0

ok, thanks :) 그러나 쿼리에 커서를 통합하여 값에 도달하면 즉시 종료 할 수 있습니까? – clarkk