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

Dan*_*Dan 6 mysql sql 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
Run Code Online (Sandbox Code Playgroud)

给我:

Category Value
1        1.3
1        1.6
2        9.5
2        9.2
3        4
3        8
Run Code Online (Sandbox Code Playgroud)

在我从sqlite3迁移之前,我必须首先从每个类别中选择最低,然后排除任何加入的类别,我必须再次选择每个类别中的最低值.然后,在类别中等于新的最低或更低的任何东西都赢了.如果出现平局,这也会选择超过2个,这很烦人......它也有很长的运行时间.

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

Bil*_*win 8

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;
Run Code Online (Sandbox Code Playgroud)

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

+----------+-------+
| category | value |
+----------+-------+
|        1 |  1.30 |
|        1 |  1.60 |
|        2 |  9.20 |
|        2 |  9.50 |
|        3 |  4.00 |
|        3 |  8.00 |
+----------+-------+
Run Code Online (Sandbox Code Playgroud)

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

与其他解决方案一样,如果存在关联,则每个类别生成2行以上.有一些方法可以构建连接条件来解决这个问题,但是我们需要在表中使用主键或唯一键,我们还必须知道打算如何解决这个问题.


Pet*_*ang 4

你可以试试这个:

SELECT * FROM (
  SELECT c.*,
        (SELECT COUNT(*)
         FROM user_category c2
         WHERE c2.category = c.category
         AND c2.value < c.value) cnt
  FROM user_category c ) uc
WHERE cnt < 2
Run Code Online (Sandbox Code Playgroud)

它应该会给你想要的结果,但要检查性能是否正常。