SQL 查询从每个类别中选择底部 2

标签 sql mysql greatest-n-per-group

在 Mysql 中,我想从每个类别中选择底部的 2 个项目

Category Value
1        1.3
1        4.8
1        3.7
1        1.6
2        9.5
2        9.9
2        9.2
2        10.3
3        4
3        8
3        16

给我:

Category Value
1        1.3
1        1.6
2        9.5
2        9.2
3        4
3        8

在我从 sqlite3 迁移之前,我必须首先从每个类别中选择一个最低的,然后排除与之相关的任何内容,我必须再次从每个类别中选择最低的。然后任何等于新的最低或更低的类别获胜。如果出现平局,这也会选择超过 2 个,这很烦人......它的运行时间也很长。

我的最终目标是计算一个人属于类别中最低的 2 个之一的次数(还有一个名称字段),这是我不知道该怎么做的一部分。 谢谢

最佳答案

SELECT c1.category, c1.value
FROM catvals c1
LEFT OUTER JOIN catvals c2
  ON (c1.category = c2.category AND c1.value > c2.value)
GROUP BY c1.category, c1.value
HAVING COUNT(*) < 2;

使用您的测试数据在 MySQL 5.1.41 上进行了测试。输出:

+----------+-------+
| category | value |
+----------+-------+
|        1 |  1.30 |
|        1 |  1.60 |
|        2 |  9.20 |
|        2 |  9.50 |
|        3 |  4.00 |
|        3 |  8.00 |
+----------+-------+

(额外的小数位是因为我将 value 列声明为 NUMERIC(9,2)。)

与其他解决方案一样,如果有联系,这会为每个类别生成超过 2 行。有一些方法可以构建连接条件来解决这个问题,但我们需要在您的表中使用主键或唯一键,而且我们还必须知道打算如何连接已解决。

关于SQL 查询从每个类别中选择底部 2,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1923613/

相关文章:

sql-server - SQL Server - 为每个 FK 选择前 5 行

sql - 如何在 PostgreSQL 中添加基于排序顺序的序号 id 字段

mysql - UPDATE 语句格式类似于 INSERT 语句

php - 在 Sphinx 中按 sql_attr_float 排序

mysql - 哪个查询被优化

sql - 如何通过每个客户端 ID 的组 ID 获取最小日期

SQL - 如何从查询结果中排除与另一行相同的行?

php - 插入查询不做任何事情

javascript - 将 session 变量附加到字符串以为 mySQL 查询创建表名

mysql - 使用 MAX DATE 和 GROUP BY 获取行