1. 程式人生 > >今天遇到一個問題,mysql取分組前幾條資料

今天遇到一個問題,mysql取分組前幾條資料

親測無誤

小提示:
建立臨時表的方式需要資料庫寫許可權,只有讀許可權的話還是用老實用巢狀sql好了

DROP TEMPORARY TABLE IF EXISTS tableWithRowNum;
CREATE TEMPORARY TABLE tableWithRowNum
  SELECT @rownum := @rownum + 1 AS rowNum, b.*
  FROM (
    SELECT @rownum := 0 AS rowNum
  ) a, (
    SELECT *
    FROM `<targetTable>`
    ORDER BY
`<groupByCol>`, `<orderByCol>` DESC ) b;
DROP TEMPORARY TABLE IF EXISTS eachGroupMinRowNum; CREATE TEMPORARY TABLE eachGroupMinRowNum SELECT `<groupByCol>`, MIN(rowNum) AS minRowNum FROM tableWithRowNum GROUP BY `<groupByCol>`; SELECT t.* FROM eachGroupMinRowNum l, tableWithRowNum t WHERE
l.`<groupByCol>` = t.`<groupByCol>` AND t.rowNum - l.minRowNum < '<linesPerGroup>';

個人例項

定義儲存過程:

delimiter $$

drop PROCEDURE if exists select_daily_top_gold$$

CREATE PROCEDURE select_daily_top_gold(IN topN INT)
BEGIN

DROP TEMPORARY TABLE IF EXISTS dailyUserSumGold;

CREATE
TEMPORARY TABLE dailyUserSumGold AS SELECT `user_id`, SUM(`gold`) AS sum_gold , LEFT(`create_time`, 10) AS daystr FROM `ml_user_gold` GROUP BY daystr, `user_id`;
DROP TEMPORARY TABLE IF EXISTS tableWithRowNum; CREATE TEMPORARY TABLE tableWithRowNum AS SELECT @rownum := @rownum + 1 AS rowNum, b.* FROM ( SELECT @rownum := 0 AS rowNum ) a, ( SELECT * FROM dailyUserSumGold ORDER BY daystr, sum_gold DESC ) b; DROP TEMPORARY TABLE IF EXISTS eachGroupMinRowNum; CREATE TEMPORARY TABLE eachGroupMinRowNum AS SELECT daystr, MIN(rowNum) AS minRowNum FROM tableWithRowNum GROUP BY daystr; END $$ delimiter ;

呼叫儲存過程:

call select_daily_top_gold(2);
SELECT t.*
FROM eachGroupMinRowNum l, tableWithRowNum t
WHERE l.`daystr` = t.`daystr`
 AND t.rowNum - l.minRowNum < 5;