选择具有最小值的所有行

use*_*292 11 sqlite

在 Sqlite 3 中,我试图弄清楚如何根据最小值选择行。我认为我对相关术语的了解不足,无法有效地搜索谷歌。

该表看起来像:

num         text        num2      
----------  ----------  ----------
0           a           1         
0           a           2         
1           a           3         
1           b           4         
Run Code Online (Sandbox Code Playgroud)

我想获取num2is1, 2和的行4。我想根据文本列的每个唯一值的 num 的最小值进行选择。

所以,对于text = 'a',最小值num0,所以我想要第 1 行和第 2 行。对于text = 'b',最小值num1,所以我想要行4

使用 group by 的各种组合,我可以得到行12或行14。我觉得我缺少一个可以做我想做的事情的 SQL 组件,但我一直无法弄清楚它可能是什么。

执行此类查询的正确方法是什么?

可能的解决方案

我找到了一种方法来做到这一点。我的声誉不足以回答我自己的问题,所以我在这里进行更新。我不确定它是否总是正确的或效率如何。欢迎提出任何意见。

我使用了一个复合选择语句,其中一个查询为文本的每个唯一值找到 num 的最小值:

sqlite> select num, text from t group by text having num = min( num );
num         text      
----------  ----------
0           a         
1           b         
Run Code Online (Sandbox Code Playgroud)

然后我将它与完整表格结合起来,以获得与这两列匹配的所有行。

sqlite> with u as
      ( select num, text from t group by text having num = min( num ) )
        select t.* from t join u on t.num = u.num and t.text = u.text;
num         text        num2      
----------  ----------  ----------
0           a           1         
0           a           2         
1           b           4         
Run Code Online (Sandbox Code Playgroud)

CL.*_*CL. 11

如您所见,简单的 GROUP BY 不起作用,因为它每个组只返回一条记录。

您的加入工作正常。对于大表,只有在连接列(numtext)。

或者,您可以使用相关子查询:

SELECT *
FROM t
WHERE num = (SELECT MIN(num)
             FROM t AS t2
             WHERE t2.text = t.text);
Run Code Online (Sandbox Code Playgroud)

SQLFiddle

执行时,此查询不需要临时表(您的查询是针对 的结果u),但会为 中的每条记录执行子查询t,因此text应建立索引。(或者在两者上使用索引textnum获得覆盖索引。)