mySQL - order by procentowe

0

Witam,

Mam problem z klauzulą order by a mianowicie chciałbym wyświetlić 10% firm w których pracownicy zarabiają najwięcej.
Mam taką tabelę o nazwie COMPANY:66eff31564.png
Wiem jak wyświetlić np. pięć firm w których zarabia się najwięcej czyli :
SELECT name from COMPANY order by zarobki miesięcznie LIMIT 5
A jak zrobić żeby wyświetliło mi się 10% firm które płacą najwięcej miesięcznie? Wiem że w T-SQL jest to polecenie TOP 10 PERCENT. Czy jest odpowiednik w mySQL ?
Proszę o pomoc

2

Możesz zrobić coś takiego:

-- 30% górnych firm

set @cnt = floor((select count(*) from firma) * 0.30);
set @qry = concat('select * from firma order by zarobki desc limit ', @cnt);
prepare myquery from @qry;
execute myquery;

dla przykładowej tabeli:

create table firma
(
	nazwa varchar(50) null,
	zarobki float null
)
1

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'...

0

dziękuję bardzo za odpowiedzi ale widzę, że to raczej jeszcze nie mój poziom bo większości nie zrozumiałęm z tego co napisaliście :(

1

...to raczej jeszcze nie mój poziom bo większości nie zrozumiałęm z tego co napisaliście.

Eee to proste, zobacz:

-- Ustawiamy zmienną o nazwie @cnt czyli `count`;
-- `SELECT COUNT(*) FROM firma` zwróci ilość wszystkich rekordów w tabeli `firma`;
-- Tę liczbę mnożymy razy `0,30` czyli chcemy uzyskać liczbę stanowiącą 30% całości rekordów;
-- `FLOOR` zaokrągli nam tę liczbę w dół. Jeżeli chcesz można użyć `CEILING` od zaokrąglenia w górę.
-- Po prostu `count` musi być liczbą całkowitą;
SET @cnt = FLOOR((SELECT COUNT(*) FROM firma) * 0.30);

-- Łączymy teraz naszą liczbę 30% wierszy z zapytaniem SQL poprzez konkatenacje
SET @qry = concat('select * from firma order by zarobki desc limit ', @cnt);

-- ...i wykonujemy zapytanie:
-- `PREPARE` przygotowuje nasze zapytanie w dynamicznym SQL z łańcucha `@qry`
-- `EXECUTE` je wykonuje
PREPARE myquery FROM @qry;
EXECUTE myquery;

Musimy posłużyć się tutaj dynamicznym SQL'em, ponieważ nie możemy w MySQL'u zrobić po prostu tak:

SET @cnt = FLOOR((SELECT COUNT(*) FROM firma) * 0.30);
select * from firma order by zarobki desc limit @cnt;

Trzeba było znaleźć hack'a :)

0

aaaa teraz to już jasne ale sam bym tego na pewno nie zrobił :P nie wiedziałem, że takie czary mary można robić ale wszystko przede mną. Dziękuję !! :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1