Thread: Select subset of rows

Select subset of rows

From
"Paulo Roberto Siqueira"
Date:
    Hi folks,
I have this table

CREATE TABLE EMPLOYEE (ID_EMP INT4 PRIMARY KEY, NAME VARCHAR(35), SALARY
NUMERIC(5,2));
I want to select only the employees' names who have the 5 highest salaries.




Paulo Siqueira



Re: Select subset of rows

From
Stephan Szabo
Date:
Of course immediately after sending the last message and logging off my
ISP I figured out the simpler way for the third one:

begin;
select salary into temp saltemp from employee order by salary desc limit 5;
select name from employee where exists (select * from saltemp wheresaltemp.salary=employee.salary);
end;

Stephan Szabo
sszabo@bigpanda.com

On Sun, 27 Aug 2000, Paulo Roberto Siqueira wrote:

>     Hi folks,
> 
>     I have this table
> 
> CREATE TABLE EMPLOYEE (ID_EMP INT4 PRIMARY KEY, NAME VARCHAR(35), SALARY
> NUMERIC(5,2));
> 
>     I want to select only the employees' names who have the 5 highest salaries.
> 
> 
> 
> 
> Paulo Siqueira
> 



Re: Select subset of rows

From
Stephan Szabo
Date:
On Sun, 27 Aug 2000, Paulo Roberto Siqueira wrote:

>     Hi folks,
> 
>     I have this table
> 
> CREATE TABLE EMPLOYEE (ID_EMP INT4 PRIMARY KEY, NAME VARCHAR(35), SALARY
> NUMERIC(5,2));
> 
>     I want to select only the employees' names who have the 5 highest salaries.

Well, that depends on what you want to do in case of duplicate salaries.

If you don't care about duplicate salaries, and you don't mind the
possibility of non-deterministic responses in some cases:
select name from employee order by salary desc limit 5;

If you want to take the 5 highest salary values and find however many
people have those salaries, I think this works:
begin;
select distinct salary into temp saltemp from employee order by salary desc limit 5;
select name from employee where exists (select * from saltemp wheresaltemp.salary=employee.salary);
end;

If you want to get at least 5 people but don't want to cut off at 5
if the 5th, 6th, etc people are tied, I'm sure there's a better way,
and I probably made at least one mistake in writing this out, but...
begin;
select distinct salary into temp saltemp from employee order by salary desc limit 5;
select salary, count(*) into temp saltemp2 from employeewhere exists(select * from saltemp where
saltemp.salary=employee.salary)group by salary;
 
select saltemp2.salary, sum(case when saltemp2_2.salary<=saltemp2.salary then 0 else saltemp2_2.count end) into temp
saltemp3from saltemp2,saltemp2 saltemp2_2 group bysaltemp2.salary;
 
select name from employee,saltemp3 where employee.salary=saltemp3.salary and saltemp3.sum<5 order by
employee.salarydesc;
end;



Re: Select subset of rows

From
John McKown
Date:
On Sun, 27 Aug 2000, Stephan Szabo wrote:

> 
> Of course immediately after sending the last message and logging off my
> ISP I figured out the simpler way for the third one:
> 
> begin;
> select salary into temp saltemp from employee order by salary desc 
>  limit 5;
> select name from employee where exists (select * from saltemp where
>  saltemp.salary=employee.salary);
> end;
> 
> Stephan Szabo
> sszabo@bigpanda.com
> 

I wonder if the following might be a bit faster? Or would it be slower?

select salary into temp saltemp from employee order by salary desc
limit 5;

select min(salary) as minsal into test minsal from saltemp;

select name, salary from employee, minsalwhere salary >= minsal;

I don't know the speed difference between my second select and your
subselect within an EXISTS clause might be.

Just a thought,
John



Re: Select subset of rows

From
Stephan Szabo
Date:
On Sun, 27 Aug 2000, John McKown wrote:

> On Sun, 27 Aug 2000, Stephan Szabo wrote:
> 
> > 
> > Of course immediately after sending the last message and logging off my
> > ISP I figured out the simpler way for the third one:
> > 
> > begin;
> > select salary into temp saltemp from employee order by salary desc 
> >  limit 5;
> > select name from employee where exists (select * from saltemp where
> >  saltemp.salary=employee.salary);
> > end;
> > 
> > Stephan Szabo
> > sszabo@bigpanda.com
> > 
> 
> I wonder if the following might be a bit faster? Or would it be slower?
> 
> select salary into temp saltemp from employee order by salary desc
> limit 5;
> 
> select min(salary) as minsal into test minsal from saltemp;
> 
> select name, salary from employee, minsal
>  where salary >= minsal;
> 
> I don't know the speed difference between my second select and your
> subselect within an EXISTS clause might be.

Not sure.  Probably depends on if the subplan/seq scan for the 
subquery on the one is more or less expensive than the time on the
additional query and processing for the query with the min.

Actually, i guess you might be able to use offset in there to get rid
of the second query too...
if you do like
select salary into temp saltemp from employee order by salary desclimit 1 offset 4;
you can probably get the 5th one right out.