在SQL中,如何为每个组选择前2行

时间:2022-04-12 12:03:04

I have a table as following:

我有一张表如下:

NAME    SCORE
-----------------
willy       1
willy       2
willy       3
zoe         4
zoe         5
zoe         6

Here's the sample

这是样本

The aggregation function for group by only allow me to get the highest score for each name. I would like to make a query to get the highest 2 score for each name, how should I do?

group by的聚合函数只允许我获得每个名称的最高分。我想进行查询以获得每个名字的最高2分,我该怎么办?

My expected output is

我的预期产量是

NAME    SCORE
-----------------
willy       2
willy       3
zoe         5
zoe         6

7 个解决方案

#1


19  

SELECT *
FROM   test s
WHERE 
        (
            SELECT  COUNT(*) 
            FROM    test  f
            WHERE f.name = s.name AND 
                  f.score >= s.score
        ) <= 2

#2


9  

In MySQL, you can use user-defined variables to get a row number in each group:

在MySQL中,您可以使用用户定义的变量来获取每个组中的行号:

select name, score
from
(
  SELECT name,
    score,
    (@row:=if(@prev=name, @row +1, if(@prev:= name, 1, 1))) rn
  FROM test123 t
  CROSS JOIN (select @row:=0, @prev:=null) c
  order by name, score desc 
) src
where rn <= 2
order by name, score;

See Demo

见演示

#3


2  

If you don't mind having additional column then you can use the following code:

如果您不介意添加其他列,则可以使用以下代码:

SELECT Name, Score, rank() over(partition by Name, order by Score DESC) as rank
From Table
Having rank < 3;

Rank function provides rank for each partition, in your case it is name

Rank函数为每个分区提供排名,在您的情况下它是名称

#4


0  

For this you can do this-

为此你可以这样做 -

http://www.sqlfiddle.com/#!2/ee665/4

http://www.sqlfiddle.com/#!2/ee665/4

but in order to get first 2 query, you should use a ID then run limit for ID like 0,2.

但是为了获得前2个查询,您应该使用ID然后运行ID为0的限制。

#5


0  

You can do somthething like this:

你可以做这样的事:

SET @num :=0, @name :='';   
SELECT name, score,
    @num := IF( @name= name, @num +1, 1 ) AS row_number,
    @name := name AS dummy
FROM test
GROUP BY name, score
HAVING row_number <=2

#6


0  

SELECT * FROM (   
    SELECT  VD.`cat_id` ,  
       @cat_count := IF( (@cat_id = VD.`cat_id`), @cat_count + 1, 1 ) AS 'DUMMY1', 
       @cat_id := VD.`cat_id` AS 'DUMMY2',
       @cat_count AS 'CAT_COUNT'   
     FROM videos VD   
     INNER JOIN categories CT ON CT.`cat_id` = VD.`cat_id`  
       ,(SELECT @cat_count :=1, @cat_id :=-1) AS CID  
     ORDER BY VD.`cat_id` ASC ) AS `CAT_DETAILS`
     WHERE `CAT_COUNT` < 4

------- STEP FOLLOW ----------  
1 . select * from ( 'FILTER_DATA_HERE' ) WHERE 'COLUMN_COUNT_CONDITION_HERE' 
2.  'FILTER_DATA_HERE'   
    1. pass 2 variable @cat_count=1 and  @cat_id = -1  
    2.  If (@cat_id "match" column_cat_id value)  
        Then  @cat_count = @cat_count + 1    
        ELSE @cat_count = 1      
    3. SET @cat_id = column_cat_id    

 3. 'COLUMN_COUNT_CONDITION_HERE'   
    1. count_column < count_number    

4. ' EXTRA THING '
   1. If you want to execute more than one statement inside " if stmt "
   2. IF(condition, stmt1 , stmt2 )
      1. stmt1 :- CONCAT(exp1, exp2, exp3) 
      2. stmt2 :- CONCAT(exp1, exp2, exp3) 
   3. Final "If" Stmt LIKE 
      1. IF ( condition , CONCAT(exp1, exp2, exp3) , CONCAT(exp1, exp2, exp3) )    

#7


-1  

Use this query.

使用此查询。

select * from fruits 
where type = 'orange'  
order by price limit 2

Solution Here:
https://www.xaprb.com/blog/2006/12/07/how-to-select-the-firstleastmax-row-per-group-in-sql/

解决方案:https://www.xaprb.com/blog/2006/12/07/how-to-select-the-firstleastmax-row-per-group-in-sql/

#1


19  

SELECT *
FROM   test s
WHERE 
        (
            SELECT  COUNT(*) 
            FROM    test  f
            WHERE f.name = s.name AND 
                  f.score >= s.score
        ) <= 2

#2


9  

In MySQL, you can use user-defined variables to get a row number in each group:

在MySQL中,您可以使用用户定义的变量来获取每个组中的行号:

select name, score
from
(
  SELECT name,
    score,
    (@row:=if(@prev=name, @row +1, if(@prev:= name, 1, 1))) rn
  FROM test123 t
  CROSS JOIN (select @row:=0, @prev:=null) c
  order by name, score desc 
) src
where rn <= 2
order by name, score;

See Demo

见演示

#3


2  

If you don't mind having additional column then you can use the following code:

如果您不介意添加其他列,则可以使用以下代码:

SELECT Name, Score, rank() over(partition by Name, order by Score DESC) as rank
From Table
Having rank < 3;

Rank function provides rank for each partition, in your case it is name

Rank函数为每个分区提供排名,在您的情况下它是名称

#4


0  

For this you can do this-

为此你可以这样做 -

http://www.sqlfiddle.com/#!2/ee665/4

http://www.sqlfiddle.com/#!2/ee665/4

but in order to get first 2 query, you should use a ID then run limit for ID like 0,2.

但是为了获得前2个查询,您应该使用ID然后运行ID为0的限制。

#5


0  

You can do somthething like this:

你可以做这样的事:

SET @num :=0, @name :='';   
SELECT name, score,
    @num := IF( @name= name, @num +1, 1 ) AS row_number,
    @name := name AS dummy
FROM test
GROUP BY name, score
HAVING row_number <=2

#6


0  

SELECT * FROM (   
    SELECT  VD.`cat_id` ,  
       @cat_count := IF( (@cat_id = VD.`cat_id`), @cat_count + 1, 1 ) AS 'DUMMY1', 
       @cat_id := VD.`cat_id` AS 'DUMMY2',
       @cat_count AS 'CAT_COUNT'   
     FROM videos VD   
     INNER JOIN categories CT ON CT.`cat_id` = VD.`cat_id`  
       ,(SELECT @cat_count :=1, @cat_id :=-1) AS CID  
     ORDER BY VD.`cat_id` ASC ) AS `CAT_DETAILS`
     WHERE `CAT_COUNT` < 4

------- STEP FOLLOW ----------  
1 . select * from ( 'FILTER_DATA_HERE' ) WHERE 'COLUMN_COUNT_CONDITION_HERE' 
2.  'FILTER_DATA_HERE'   
    1. pass 2 variable @cat_count=1 and  @cat_id = -1  
    2.  If (@cat_id "match" column_cat_id value)  
        Then  @cat_count = @cat_count + 1    
        ELSE @cat_count = 1      
    3. SET @cat_id = column_cat_id    

 3. 'COLUMN_COUNT_CONDITION_HERE'   
    1. count_column < count_number    

4. ' EXTRA THING '
   1. If you want to execute more than one statement inside " if stmt "
   2. IF(condition, stmt1 , stmt2 )
      1. stmt1 :- CONCAT(exp1, exp2, exp3) 
      2. stmt2 :- CONCAT(exp1, exp2, exp3) 
   3. Final "If" Stmt LIKE 
      1. IF ( condition , CONCAT(exp1, exp2, exp3) , CONCAT(exp1, exp2, exp3) )    

#7


-1  

Use this query.

使用此查询。

select * from fruits 
where type = 'orange'  
order by price limit 2

Solution Here:
https://www.xaprb.com/blog/2006/12/07/how-to-select-the-firstleastmax-row-per-group-in-sql/

解决方案:https://www.xaprb.com/blog/2006/12/07/how-to-select-the-firstleastmax-row-per-group-in-sql/