Query in sql to get the top 10 percent in standard sql (without limit, top and the likes, without window functions)

StackOverflow https://stackoverflow.com/questions/21959845

  •  15-10-2022
  •  | 
  •  

Domanda

I'm wondering how to retrieve the top 10% athletes in terms of points, without using any clauses such as TOP, Limit etc, just a plain SQL query.

My idea so far:

Table Layout:

Score:

ID | Name | Points

Query:

select *
from Score s
where 0.10 * (select count(*) from Score x) >
     (select count(*) from Score p where p.Points < s.Points)

Is there an easier way to do this? Any suggestions?

È stato utile?

Soluzione 2

Try:

select s1.id, s1.name s1.points, count(s2.points)
from score s1, score s2
where s2.points > s1.points
group by s1.id, s1.name s1.points
having count(s2.points) <= (select count(*)*.1 from score)

Basically calculates the count of players with a higher score than the current score, and if that count is less than or equal to 10% of the count of all scores, it's in the top 10%.

Altri suggerimenti

In most databases, you would use the ANSI standard window functions:

select s.*
from (select s.*,
             count(*) over () as cnt,
             row_number() over (order by score) as seqnum
      from s
     ) s
where seqnum*10 < cnt;

The PERCENTILE_DISC function is standard SQL and can help you here. Not every SQL implementation supports it, but the following should work in SQL Server 2012, for example. If you need to be particular about ties, or what the top 10% means if there are fewer than 10 athletes, make sure this is computing what you want. PERCENTILE_COMP may be a better option for some questions.

WITH C(cutoff) AS (
  SELECT DISTINCT
    PERCENTILE_DISC(0.90)
      WITHIN GROUP (ORDER BY points)
      OVER ()
  FROM T
)
  SELECT *
  FROM Score JOIN C
  ON points >= cutoff;
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top