2011-01-14 40 views
4

可以說我有SQL記錄:MySQL的選擇N記錄在GROUP BY基地

 
Country | Number 
USA | 300 
USA | 450 
USA | 500 
USA | 100 
UK | 300 
UK | 400 
UK | 1000 

而且我在做這樣的事情:SELECT * FROM table GROUP BY Country
如果我想選擇在每個國家/地區僅顯示2個最大數字的結果?我怎樣才能存檔這個?

其結果將是:

 
Country | Number 
USA | 450 
USA | 500 
UK | 400 
UK | 1000 
+0

還,如果你在第二個位置有重複的「數量」值......你只需要在這個速度的一個數字實例? – DRapp 2011-01-14 13:56:54

回答

1

由於MySQL不具有一個內置的RANK函數,查詢可能會很慢:

SET @cRank = 0; 
SET @cCoutnry = ''; 

SELECT Country, Number 
FROM (
    SELECT Number, @cRank := IF(@cCoutnry = Country, @cRank+1, 1) AS rank, @cCoutnry := Country Country 
    FROM table 
    ORDER BY Country, Number DESC 
) rs 
WHERE rank < 3 
+0

除了使用表中的每一行之外,你還有更好的選擇嗎? – ajreal 2011-01-14 07:58:01

+0

@ajreal無法想到更快的任何事情,你可以試着用一個子查詢來做這件事,這個子查詢將返回最大值,並且在主查詢中WHERE數字 2011-01-14 08:05:32

0

讓命名錶TNAME,那麼他們的查詢將是。

SELECT * FROM (SELECT ROW_NUMBER() OVER (PARTITION BY X.Country) AS RowNo, * 
FROM (SELECT Country, Name FROM TName ORDER BY Country, Number) X) Y WHERE Y.RowNo <= 2 
2

的樣本數據

create table data (Country varchar(10), Number int); 
insert into data select 
'USA' , 300 union all select 
'USA' , 450 union all select 
'USA' , 500 union all select 
'USA' , 100 union all select 
'FR' , 100 union all select 
'FR' , 420 union all select 
'UK' , 300 union all select 
'UK' , 400 union all select 
'UK' , 1000; 

第一種選擇是使用像Scrum的梅斯特變量僞排名顯示,但這裏作爲一個單獨的語句

SELECT Country, Number 
FROM (
    SELECT 
     Number, 
     @r := case when @c=country then @r+1 else 1 end rownum, 
     @c := Country Country 
    FROM (select @r :=0 , @c := '') x, data 
    ORDER BY Country, Number DESC 
) y 
WHERE rownum < 3; 

如果您正在使用這在前端,只需要2個計數,那麼你可以使用這個表格返回一個列表中的計數(單列)

SELECT 
    Country, 
    left(x,locate(',',concat(x,','),locate(',',x)+1)-1) Numbers 
FROM (
    SELECT 
     a.Country, 
     Group_Concat(a.Number) x 
    From (
     select country, number 
     from data 
     order by country, number desc) a 
    group by a.Country 
) b 

結果是

"Country";"Numbers" 
"FR";"420,100" 
"UK";"1000,400" 
"USA";"500,450" 

如果有可能發生聯繫,則第二形式的該變型中刪除關係並示出了「每個國家頂部2個不同的數字」,作爲記錄。

SELECT distinct x.Country, x.Number 
From data x 
inner join 
(
    SELECT 
     Country, 
     left(x,locate(',',concat(x,','),locate(',',x)+1)-1) Numbers 
    FROM (
     SELECT 
      a.Country, 
      Group_Concat(a.Number) x 
     From (
      select distinct country, number 
      from data 
      order by country, number desc) a 
     group by a.Country 
    ) b 
) y on x.Country=y.Country 
    and concat(',',y.Numbers,',') like concat('%,',x.Number,',%') 
order by x.Country, x.Number Desc 

結果

"Country";"Number" 
"FR";"420" 
"FR";"100" 
"UK";"1000" 
"UK";"400" 
"USA";"500" 
"USA";"450"