抓取每個分組結果中的前n筆記錄
P粉785957729
P粉785957729 2023-08-21 19:55:22
0
2
462
<p>以下是最簡單的可能範例,但任何解決方案都應能夠擴展到所需的n個頂部結果:</p> <p>給定以下表格,其中包含人員、組別和年齡列,如何取得每個組別中年齡最大的2個人? (組內的並列情況不應產生更多結果,而是按字母順序給出前2個)</p> <pre> -------- ------- ----- | Person | Group | Age | -------- ------- ----- | Bob | 1 | 32 | | Jill | 1 | 34 | | Shawn | 1 | 42 | | Jake | 2 | 29 | | Paul | 2 | 36 | | Laura | 2 | 39 | -------- ------- ----- </pre> <p>期望的結果集:</p> <pre> -------- ------- ----- | Shawn | 1 | 42 | | Jill | 1 | 34 | | Laura | 2 | 39 | | Paul | 2 | 36 | -------- ------- ----- </pre> <hr> <p><strong>注意:</strong>這個問題是基於之前的一個問題——獲取每個組的最大值的記錄的SQL結果- 用於獲取每個組的單個頂部行,並且從@Bohemian獲得了一個很好的MySQL特定的答案:</p> <pre class="brush:php;toolbar:false;">select * from (select * from mytable order by `Group`, Age desc, Person) x group by `Group`</pre> <p>很想能夠在此基礎上繼續構建,但我看不出如何做到。 </p>
P粉785957729
P粉785957729

全部回覆(2)
P粉340264283

在其他資料庫中,您可以使用ROW_NUMBER來實現此功能。 MySQL不支援ROW_NUMBER,但您可以使用變數來模擬它:

SELECT
    person,
    groupname,
    age
FROM
(
    SELECT
        person,
        groupname,
        age,
        @rn := IF(@prev = groupname, @rn + 1, 1) AS rn,
        @prev := groupname
    FROM mytable
    JOIN (SELECT @prev := NULL, @rn := 0) AS vars
    ORDER BY groupname, age DESC, person
) AS T1
WHERE rn <= 2

線上示範: sqlfiddle

#

編輯 我剛剛注意到bluefeet發布了一個非常相似的答案:給他 1。但是這個答案有兩個小優點:

  1. 這是一個單一查詢。變數在SELECT語句內部初始化。
  2. 它處理了問題中描述的並列情況(按名稱的字母順序)。

因此,我將保留它,以防它能幫助某人。

P粉404539732

以下是一種方法,使用UNION ALL(請參閱帶有示範的SQL Fiddle)。這適用於兩個群組,如果你有多個群組,則需要指定group編號並為每個group新增查詢:

(
  select *
  from mytable 
  where `group` = 1
  order by age desc
  LIMIT 2
)
UNION ALL
(
  select *
  from mytable 
  where `group` = 2
  order by age desc
  LIMIT 2
)

有多種方法可以實現這個目標,請參考本文以確定適合您情況的最佳方法:

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

編輯:

這也可能適用於您,它為每筆記錄產生一個行號。使用上面連結中的範例,它將只傳回行號小於或等於2的記錄:

select person, `group`, age
from 
(
   select person, `group`, age,
      (@num:=if(@group = `group`, @num +1, if(@group := `group`, 1, 1))) row_number 
  from test t
  CROSS JOIN (select @num:=0, @group:=null) c
  order by `Group`, Age desc, person
) as x 
where x.row_number <= 2;

請參考演示

#
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板