在 Sqlite 3 中,我试图弄清楚如何根据最小值选择行。我认为我对相关术语的了解不足,无法有效地搜索谷歌。
该表看起来像:
num text num2
---------- ---------- ----------
0 a 1
0 a 2
1 a 3
1 b 4
Run Code Online (Sandbox Code Playgroud)
我想获取num2
is1, 2
和的行4
。我想根据文本列的每个唯一值的 num 的最小值进行选择。
所以,对于text = 'a'
,最小值num
是0
,所以我想要第 1 行和第 2 行。对于text = 'b'
,最小值num
是1
,所以我想要行4
。
使用 group by 的各种组合,我可以得到行1
和2
或行1
和4
。我觉得我缺少一个可以做我想做的事情的 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 不起作用,因为它每个组只返回一条记录。
您的加入工作正常。对于大表,只有在连接列(num
和text
)。
或者,您可以使用相关子查询:
SELECT *
FROM t
WHERE num = (SELECT MIN(num)
FROM t AS t2
WHERE t2.text = t.text);
Run Code Online (Sandbox Code Playgroud)
执行时,此查询不需要临时表(您的查询是针对 的结果u
),但会为 中的每条记录执行子查询t
,因此text
应建立索引。(或者在两者上使用索引text
并num
获得覆盖索引。)