Możesz skorzystać ze zmiannych MySQL-owych. Będzie najwydajniej, bo 'jednoprzebiegowo'...
SQLFiddle wysiadło (http://sqlfiddle.com/#!9/9a48e7/4), więc tu ci wkleję :
create table firmy(nazwa varchar(20) not null unique, zarobki integer );
insert into firmy values('Casio', 1000),
('Kawasaki', 570),
('Prada', 1350),
('Nokia', 800),
('Tesco', 450),
('Shell', 1100),
('Pepsi', 790),
('Lenovo', 900),
('Kyocera', 150),
('Motorola', 2000),
('Xerox', 1700),
('Philips', 850),
('Red Hat', 290),
('Skanska', 670),
('Vodafone', 800),
('Yamaha', 1350),
('Twitter', 1900);
select f.*, @lp:=@lp+1 lp from firmy f, (select @lp:=0) x order by zarobki desc;
-- 30% firm 'od góry' - dla 10% ttlko jedna się łapała...
select * from (select f.*, @lp:=@lp+1 lp from firmy f, (select @lp:=0) x
order by zarobki desc) X
where lp<@lp*.30
;
-- firmy, które mają 30% zarobków
select * from (
select f.*, @suma:=@suma+zarobki suma from firmy f, (select @suma:=0) x order by zarobki desc
) x
where suma<@suma*.3
;
Aby przyspieszyć załóż indeks na 'zarobki'...