2011-11-02 71 views
0

我想通过总和来限制mySQL中的SELECT结果。 例如,这是我的表:MySQL总和限制

(id, val) 

数据条目: (1100), (2300), (3,50), (4,3000)

我想选择第一个 k个条目,使得这些条目中的val的总和刚好足以使其达到M. 例如,我想查找M = 425的条目。 结果应该是(1,100),( 2300),(3,50)。

我该如何在mysql select查询中做到这一点?

回答

0

从MySQL参考手册:

LIMIT子句可以用来限制由SELECT语句返回的行的数目。 LIMIT需要一个或两个数字参数,它们都必须是非负整数常量(除了使用预准备语句时)。

所以你不能用你提出的方式来限制。要达到您想要的效果,您需要使用您的应用程序(java,c,php或其他),逐行读取结果集,并在达到条件时停止。

或者你可以使用预先准备好的语句,但无论如何你不能有条件限制(它必须是一个常数值),它并不完全符合你的要求。

2

试试这个变种 -

SET @sum = 0; 
SELECT id, val FROM (
    SELECT *, @sum:[email protected] + val mysum FROM mytable2 ORDER BY id 
) t 
WHERE mysum <= 450; 

+------+------+ 
| id | val | 
+------+------+ 
| 1 | 100 | 
| 2 | 300 | 
| 3 | 50 | 
+------+------+ 
1

此存储过程可以帮助:

DELIMITER ;; 

CREATE PROCEDURE selectLimitBySum (IN m INT) 
BEGIN 
DECLARE mTmp INT DEFAULT 0; 
DECLARE idTmp INT DEFAULT 0; 
DECLARE valTmp INT DEFAULT 0; 
DECLARE doneLoop SMALLINT DEFAULT 0; 
DECLARE crsSelect CURSOR FOR SELECT id, val FROM test3; 
DECLARE CONTINUE HANDLER FOR NOT FOUND SET doneLoop = 1; 
OPEN crsSelect; 
aloop: LOOP 
    SET idTmp = 0; 
    SET valTmp = 0; 
    FETCH crsSelect INTO idTmp, valTmp; 
    if doneLoop THEN 
     LEAVE aloop; 
    END IF; 
    SELECT idTmp, valTmp; 
    SET mTmp = mTmp + valTmp; 
    if mTmp > m THEN 
     LEAVE aloop; 
    END IF; 
END LOOP; 
CLOSE crsSelect; 
END ;; 

DELIMITER ; 

请随意更改表名或变量名,按您的需求。

0
create table #limit(
id int, 
val int 
) 

declare @sum int, @id int, @val int, @m int; 
    set @sum=0; 
    set @m=250; --Value of an entry 
    declare limit_cursor cursor for 
    select id, val from your_table order by id 
    open limit_cursor 
    fetch next from limit_cursor into @id, @val 
    while(@@fetch_status=0) 
    begin 
     if(@sum<@m) 
     begin 
      set @sum = @[email protected]; 
      INSERT INTO #limit values (@id, @val); 
      fetch next from limit_cursor into @id, @val 
     end 
    else 
    begin 
    goto case1; 
    end 
    end 
    case1: 
    close limit_cursor 
    deallocate limit_cursor 
    select * from #limit 
    truncate table #limit