2011-11-02 5 views
0

Я хочу ограничить свои SELECT результаты mySQL суммой. Для примера, это мой стол:Ограничение MySQL по сумме

(id, val) 

записи данных: (1100), (2300), (3,50), (4,3000)

Я хочу, чтобы выбрать первых k записей таких, что сумма val в этих записях достаточно, чтобы добраться до М. Например, я хочу найти такие записи, что M = 425. Результат должен быть (1,100), (2300), (3,50).

Как это сделать в запросе на выбор mysql?

ответ

0

из Справочного руководства по MySQL:

Предложение LIMIT может использоваться для ограничения количества строк, возвращаемых ЗЕЬЕСТОМ. 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 
Смежные вопросы