今天遇到一個問題,mysql取分組前幾條資料
阿新 • • 發佈:2019-02-10
親測無誤
小提示:
建立臨時表的方式需要資料庫寫許可權,只有讀許可權的話還是用老實用巢狀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;