MySQL, Хранимые процедуры и функции, как вернуть multiple rows?
Если в процедуре нужно построчно обходить результат выборки, то придётся использовать курсорСREATE PROCEDURE curdemo()
BEGIN
  DECLARE done INT DEFAULT FALSE;
  DECLARE a CHAR(16);
  DECLARE b INT;

  DECLARE cur CURSOR FOR SELECT id, data FROM t1;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

  OPEN cur;
  read_loop: LOOP
    FETCH cur INTO a, b;
    IF done THEN
      LEAVE read_loop;
    END IF;
    здесь выполняются нужные действия
  END LOOP;

  CLOSE cur;
END
Процедура может возвращать результат селекта. Я бы даже сказал чаще всего так и бывает. А вот возвращающие что-то одно (функции) - пореже. 
Как типичный вариант - на входе получает кучку параметров-фильтров, флагов, а на выходе вываливает селект с отбором, сортировкой, группировкой по этим флагам.
Как тупой образчик  отбор контактов:
create procedure get_contacts (idescr char, itype int, show_hidden bit ) 
begin
... делаем кучи каких-нибудь проверок
и где-то в конце 
select ... from ... join .... 
where contacts.descr like idescr 
and (itype=0 or contacts.type=itype) 
and (show_hidden=1 or contacts.is_hidden=0)
end 
вызвав процедуру с параметрами '%%', 0, 1 - получим всех контрагентов, '%%', 0, 0 - только тех у кого не взведен флаг "скрытый" и т.п.
естественно пример примитивный и не учитывает кучи всего - сам принцип.