Mysql 使用SQL获取表的前k个记录/行

Mysql 使用SQL获取表的前k个记录/行,mysql,sql,Mysql,Sql,给定下面这样一个表,如何在不使用LIMIT或TOP的情况下获得它的前k行 k=3的期望结果: k=4的期望结果: 我需要复制MySQL的LIMIT函数而不使用它。您可以通过对派生表中的行进行编号,然后选择具有行号的行,直到达到阈值 对于MySQL,查询可能如下所示: SELECT * FROM (SELECT @row_number:=@row_number + 1 AS row_number, person,

给定下面这样一个表,如何在不使用LIMIT或TOP的情况下获得它的前k行

k=3的期望结果:

k=4的期望结果:


我需要复制MySQL的LIMIT函数而不使用它。

您可以通过对派生表中的行进行编号,然后选择具有行号的行,直到达到阈值

对于MySQL,查询可能如下所示:

SELECT 
    *
FROM
    (SELECT 
        @row_number:=@row_number + 1 AS row_number,
            person,
            `group`,
            age
    FROM
        your_table, (SELECT @row_number:=0) AS r
    ORDER BY `group` , age) x
WHERE
    row_number <= 3;
SET @position := 0;

SELECT person, groupCol, age
FROM(
  SELECT person, groupCol, age, @position := @position + 1 AS position
  FROM myTable
  ORDER BY groupCol, age) tmp
WHERE tmp.position <= 3;

为此,可以对派生表中的行进行编号,然后选择行编号高达阈值的行

对于MySQL,查询可能如下所示:

SELECT 
    *
FROM
    (SELECT 
        @row_number:=@row_number + 1 AS row_number,
            person,
            `group`,
            age
    FROM
        your_table, (SELECT @row_number:=0) AS r
    ORDER BY `group` , age) x
WHERE
    row_number <= 3;
SET @position := 0;

SELECT person, groupCol, age
FROM(
  SELECT person, groupCol, age, @position := @position + 1 AS position
  FROM myTable
  ORDER BY groupCol, age) tmp
WHERE tmp.position <= 3;

看起来您是先按组号排序,然后按年龄排序。您可以做的是按该顺序选择行,并使用变量在列表中存储它们的位置

获得该参数后,可以选择位置小于或等于参数k的行,如下所示:

SELECT 
    *
FROM
    (SELECT 
        @row_number:=@row_number + 1 AS row_number,
            person,
            `group`,
            age
    FROM
        your_table, (SELECT @row_number:=0) AS r
    ORDER BY `group` , age) x
WHERE
    row_number <= 3;
SET @position := 0;

SELECT person, groupCol, age
FROM(
  SELECT person, groupCol, age, @position := @position + 1 AS position
  FROM myTable
  ORDER BY groupCol, age) tmp
WHERE tmp.position <= 3;

看起来您是先按组号排序,然后按年龄排序。您可以做的是按该顺序选择行,并使用变量在列表中存储它们的位置

获得该参数后,可以选择位置小于或等于参数k的行,如下所示:

SELECT 
    *
FROM
    (SELECT 
        @row_number:=@row_number + 1 AS row_number,
            person,
            `group`,
            age
    FROM
        your_table, (SELECT @row_number:=0) AS r
    ORDER BY `group` , age) x
WHERE
    row_number <= 3;
SET @position := 0;

SELECT person, groupCol, age
FROM(
  SELECT person, groupCol, age, @position := @position + 1 AS position
  FROM myTable
  ORDER BY groupCol, age) tmp
WHERE tmp.position <= 3;

嗯。如果不允许变量,您仍然可以这样做

SELECT some, stuff 
  FROM an_instance x 
  JOIN another_instance y 
    ON (y.something < x.something) 
    OR (y.something = x.something AND y.some_other_thing <= x.some_other_thing) 
 GROUP  
    BY x.something,x.some_other_thing
HAVING COUNT(*) <= whatever;

…但在更大的数据集上,它的扩展性会非常糟糕。

好的。如果不允许变量,您仍然可以这样做

SELECT some, stuff 
  FROM an_instance x 
  JOIN another_instance y 
    ON (y.something < x.something) 
    OR (y.something = x.something AND y.some_other_thing <= x.some_other_thing) 
 GROUP  
    BY x.something,x.some_other_thing
HAVING COUNT(*) <= whatever;


…但在更大的数据集上,它的扩展性会非常糟糕。

使用where group=1。您使用的是什么数据库?数据应该如何排序?这是一个难题还是你有什么理由不能使用LIMIT或TOP?您可以使用光标将行添加到临时表中。@GordonLinoff我想他说的是k是一个可以是任意数字的变量。所以,k=3表示前3行,它们恰好都有一个组=1@Strawberry你有答案吗?虽然这是一项作业,但这个问题是挑战性的。使用的是什么数据库?数据应该如何排序?这是一个难题还是你有什么理由不能使用LIMIT或TOP?您可以使用光标将行添加到临时表中。@GordonLinoff我想他说的是k是一个可以是任意数字的变量。所以,k=3表示前3行,它们恰好都有一个组=1@Strawberry你有答案吗?虽然这是一项任务,但这个问题很有挑战性。你的答案正是我所想的。我真的想不出不使用“限制”的另一种方法。@Jim FWIW,我可以想出另一种方法——尽管速度较慢!你的答案正是我所想的。我真的想不出不使用“限制”的另一种方法。@Jim FWIW,我可以想出另一种方法——尽管速度较慢!不是基于信仰,我在将您的查询复制到我的编辑器时输入错误。我的错。我很感激这个答案。你能不能把它放在一个问号里?那是什么东西?@SHAKIRSHABBIR某个je-ne sais Quoi这个答案被投票通过并被接受了,这对我来说很好。但这也很遗憾,因为jpw的解决方案更好——不是基于信念,我在将您的查询复制到我的编辑器时犯了一个错误。我的错。我很感激这个答案。你能不能把它放在一个问号里?那是什么东西?@SHAKIRSHABBIR某个je-ne sais Quoi这个答案被投票通过并被接受了,这对我来说很好。但这也很遗憾,因为jpw的解决方案更好