亲测无误
小提示:
创建临时表的方式需要数据库写权限,只有读权限的话还是用老实用嵌套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;