今天遇到一个问题,得前辈点拨,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;

猜你喜欢

转载自blog.csdn.net/u010746357/article/details/81363510
今日推荐